LLVM 20.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"
32#include "llvm/IR/Module.h"
36
37using namespace llvm;
38
39#define GEN_CHECK_COMPRESS_INSTR
40#include "RISCVGenCompressInstEmitter.inc"
41
42#define GET_INSTRINFO_CTOR_DTOR
43#define GET_INSTRINFO_NAMED_OPS
44#include "RISCVGenInstrInfo.inc"
45
47 "riscv-prefer-whole-register-move", cl::init(false), cl::Hidden,
48 cl::desc("Prefer whole register move for vector registers."));
49
51 "riscv-force-machine-combiner-strategy", cl::Hidden,
52 cl::desc("Force machine combiner to use a specific strategy for machine "
53 "trace metrics evaluation."),
54 cl::init(MachineTraceStrategy::TS_NumStrategies),
55 cl::values(clEnumValN(MachineTraceStrategy::TS_Local, "local",
56 "Local strategy."),
57 clEnumValN(MachineTraceStrategy::TS_MinInstrCount, "min-instr",
58 "MinInstrCount strategy.")));
59
61
62using namespace RISCV;
63
64#define GET_RISCVVPseudosTable_IMPL
65#include "RISCVGenSearchableTables.inc"
66
67} // namespace llvm::RISCVVPseudosTable
68
69namespace llvm::RISCV {
70
71#define GET_RISCVMaskedPseudosTable_IMPL
72#include "RISCVGenSearchableTables.inc"
73
74} // end namespace llvm::RISCV
75
77 : RISCVGenInstrInfo(RISCV::ADJCALLSTACKDOWN, RISCV::ADJCALLSTACKUP),
78 STI(STI) {}
79
81 if (STI.hasStdExtCOrZca())
82 return MCInstBuilder(RISCV::C_NOP);
83 return MCInstBuilder(RISCV::ADDI)
84 .addReg(RISCV::X0)
85 .addReg(RISCV::X0)
86 .addImm(0);
87}
88
90 int &FrameIndex) const {
91 unsigned Dummy;
92 return isLoadFromStackSlot(MI, FrameIndex, Dummy);
93}
94
96 int &FrameIndex,
97 unsigned &MemBytes) const {
98 switch (MI.getOpcode()) {
99 default:
100 return 0;
101 case RISCV::LB:
102 case RISCV::LBU:
103 MemBytes = 1;
104 break;
105 case RISCV::LH:
106 case RISCV::LH_INX:
107 case RISCV::LHU:
108 case RISCV::FLH:
109 MemBytes = 2;
110 break;
111 case RISCV::LW:
112 case RISCV::LW_INX:
113 case RISCV::FLW:
114 case RISCV::LWU:
115 MemBytes = 4;
116 break;
117 case RISCV::LD:
118 case RISCV::FLD:
119 MemBytes = 8;
120 break;
121 }
122
123 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
124 MI.getOperand(2).getImm() == 0) {
125 FrameIndex = MI.getOperand(1).getIndex();
126 return MI.getOperand(0).getReg();
127 }
128
129 return 0;
130}
131
133 int &FrameIndex) const {
134 unsigned Dummy;
135 return isStoreToStackSlot(MI, FrameIndex, Dummy);
136}
137
139 int &FrameIndex,
140 unsigned &MemBytes) const {
141 switch (MI.getOpcode()) {
142 default:
143 return 0;
144 case RISCV::SB:
145 MemBytes = 1;
146 break;
147 case RISCV::SH:
148 case RISCV::SH_INX:
149 case RISCV::FSH:
150 MemBytes = 2;
151 break;
152 case RISCV::SW:
153 case RISCV::SW_INX:
154 case RISCV::FSW:
155 MemBytes = 4;
156 break;
157 case RISCV::SD:
158 case RISCV::FSD:
159 MemBytes = 8;
160 break;
161 }
162
163 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
164 MI.getOperand(2).getImm() == 0) {
165 FrameIndex = MI.getOperand(1).getIndex();
166 return MI.getOperand(0).getReg();
167 }
168
169 return 0;
170}
171
173 const MachineInstr &MI) const {
174 switch (RISCV::getRVVMCOpcode(MI.getOpcode())) {
175 case RISCV::VMV_V_X:
176 case RISCV::VFMV_V_F:
177 case RISCV::VMV_V_I:
178 case RISCV::VMV_S_X:
179 case RISCV::VFMV_S_F:
180 case RISCV::VID_V:
181 return MI.getOperand(1).isUndef();
182 default:
184 }
185}
186
187static bool forwardCopyWillClobberTuple(unsigned DstReg, unsigned SrcReg,
188 unsigned NumRegs) {
189 return DstReg > SrcReg && (DstReg - SrcReg) < NumRegs;
190}
191
193 const MachineBasicBlock &MBB,
196 RISCVII::VLMUL LMul) {
198 return false;
199
200 assert(MBBI->getOpcode() == TargetOpcode::COPY &&
201 "Unexpected COPY instruction.");
202 Register SrcReg = MBBI->getOperand(1).getReg();
204
205 bool FoundDef = false;
206 bool FirstVSetVLI = false;
207 unsigned FirstSEW = 0;
208 while (MBBI != MBB.begin()) {
209 --MBBI;
210 if (MBBI->isMetaInstruction())
211 continue;
212
213 if (MBBI->getOpcode() == RISCV::PseudoVSETVLI ||
214 MBBI->getOpcode() == RISCV::PseudoVSETVLIX0 ||
215 MBBI->getOpcode() == RISCV::PseudoVSETIVLI) {
216 // There is a vsetvli between COPY and source define instruction.
217 // vy = def_vop ... (producing instruction)
218 // ...
219 // vsetvli
220 // ...
221 // vx = COPY vy
222 if (!FoundDef) {
223 if (!FirstVSetVLI) {
224 FirstVSetVLI = true;
225 unsigned FirstVType = MBBI->getOperand(2).getImm();
226 RISCVII::VLMUL FirstLMul = RISCVVType::getVLMUL(FirstVType);
227 FirstSEW = RISCVVType::getSEW(FirstVType);
228 // The first encountered vsetvli must have the same lmul as the
229 // register class of COPY.
230 if (FirstLMul != LMul)
231 return false;
232 }
233 // Only permit `vsetvli x0, x0, vtype` between COPY and the source
234 // define instruction.
235 if (MBBI->getOperand(0).getReg() != RISCV::X0)
236 return false;
237 if (MBBI->getOperand(1).isImm())
238 return false;
239 if (MBBI->getOperand(1).getReg() != RISCV::X0)
240 return false;
241 continue;
242 }
243
244 // MBBI is the first vsetvli before the producing instruction.
245 unsigned VType = MBBI->getOperand(2).getImm();
246 // If there is a vsetvli between COPY and the producing instruction.
247 if (FirstVSetVLI) {
248 // If SEW is different, return false.
249 if (RISCVVType::getSEW(VType) != FirstSEW)
250 return false;
251 }
252
253 // If the vsetvli is tail undisturbed, keep the whole register move.
254 if (!RISCVVType::isTailAgnostic(VType))
255 return false;
256
257 // The checking is conservative. We only have register classes for
258 // LMUL = 1/2/4/8. We should be able to convert vmv1r.v to vmv.v.v
259 // for fractional LMUL operations. However, we could not use the vsetvli
260 // lmul for widening operations. The result of widening operation is
261 // 2 x LMUL.
262 return LMul == RISCVVType::getVLMUL(VType);
263 } else if (MBBI->isInlineAsm() || MBBI->isCall()) {
264 return false;
265 } else if (MBBI->getNumDefs()) {
266 // Check all the instructions which will change VL.
267 // For example, vleff has implicit def VL.
268 if (MBBI->modifiesRegister(RISCV::VL, /*TRI=*/nullptr))
269 return false;
270
271 // Only converting whole register copies to vmv.v.v when the defining
272 // value appears in the explicit operands.
273 for (const MachineOperand &MO : MBBI->explicit_operands()) {
274 if (!MO.isReg() || !MO.isDef())
275 continue;
276 if (!FoundDef && TRI->regsOverlap(MO.getReg(), SrcReg)) {
277 // We only permit the source of COPY has the same LMUL as the defined
278 // operand.
279 // There are cases we need to keep the whole register copy if the LMUL
280 // is different.
281 // For example,
282 // $x0 = PseudoVSETIVLI 4, 73 // vsetivli zero, 4, e16,m2,ta,m
283 // $v28m4 = PseudoVWADD_VV_M2 $v26m2, $v8m2
284 // # The COPY may be created by vlmul_trunc intrinsic.
285 // $v26m2 = COPY renamable $v28m2, implicit killed $v28m4
286 //
287 // After widening, the valid value will be 4 x e32 elements. If we
288 // convert the COPY to vmv.v.v, it will only copy 4 x e16 elements.
289 // FIXME: The COPY of subregister of Zvlsseg register will not be able
290 // to convert to vmv.v.[v|i] under the constraint.
291 if (MO.getReg() != SrcReg)
292 return false;
293
294 // In widening reduction instructions with LMUL_1 input vector case,
295 // only checking the LMUL is insufficient due to reduction result is
296 // always LMUL_1.
297 // For example,
298 // $x11 = PseudoVSETIVLI 1, 64 // vsetivli a1, 1, e8, m1, ta, mu
299 // $v8m1 = PseudoVWREDSUM_VS_M1 $v26, $v27
300 // $v26 = COPY killed renamable $v8
301 // After widening, The valid value will be 1 x e16 elements. If we
302 // convert the COPY to vmv.v.v, it will only copy 1 x e8 elements.
303 uint64_t TSFlags = MBBI->getDesc().TSFlags;
305 return false;
306
307 // If the producing instruction does not depend on vsetvli, do not
308 // convert COPY to vmv.v.v. For example, VL1R_V or PseudoVRELOAD.
309 if (!RISCVII::hasSEWOp(TSFlags) || !RISCVII::hasVLOp(TSFlags))
310 return false;
311
312 // Found the definition.
313 FoundDef = true;
314 DefMBBI = MBBI;
315 break;
316 }
317 }
318 }
319 }
320
321 return false;
322}
323
326 const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc,
327 const TargetRegisterClass *RegClass) const {
329 RISCVII::VLMUL LMul = RISCVRI::getLMul(RegClass->TSFlags);
330 unsigned NF = RISCVRI::getNF(RegClass->TSFlags);
331
332 uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
333 uint16_t DstEncoding = TRI->getEncodingValue(DstReg);
334 auto [LMulVal, Fractional] = RISCVVType::decodeVLMUL(LMul);
335 assert(!Fractional && "It is impossible be fractional lmul here.");
336 unsigned NumRegs = NF * LMulVal;
337 bool ReversedCopy =
338 forwardCopyWillClobberTuple(DstEncoding, SrcEncoding, NumRegs);
339 if (ReversedCopy) {
340 // If the src and dest overlap when copying a tuple, we need to copy the
341 // registers in reverse.
342 SrcEncoding += NumRegs - 1;
343 DstEncoding += NumRegs - 1;
344 }
345
346 unsigned I = 0;
347 auto GetCopyInfo = [&](uint16_t SrcEncoding, uint16_t DstEncoding)
348 -> std::tuple<RISCVII::VLMUL, const TargetRegisterClass &, unsigned,
349 unsigned, unsigned> {
350 if (ReversedCopy) {
351 // For reversed copying, if there are enough aligned registers(8/4/2), we
352 // can do a larger copy(LMUL8/4/2).
353 // Besides, we have already known that DstEncoding is larger than
354 // SrcEncoding in forwardCopyWillClobberTuple, so the difference between
355 // DstEncoding and SrcEncoding should be >= LMUL value we try to use to
356 // avoid clobbering.
357 uint16_t Diff = DstEncoding - SrcEncoding;
358 if (I + 8 <= NumRegs && Diff >= 8 && SrcEncoding % 8 == 7 &&
359 DstEncoding % 8 == 7)
360 return {RISCVII::LMUL_8, RISCV::VRM8RegClass, RISCV::VMV8R_V,
361 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
362 if (I + 4 <= NumRegs && Diff >= 4 && SrcEncoding % 4 == 3 &&
363 DstEncoding % 4 == 3)
364 return {RISCVII::LMUL_4, RISCV::VRM4RegClass, RISCV::VMV4R_V,
365 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
366 if (I + 2 <= NumRegs && Diff >= 2 && SrcEncoding % 2 == 1 &&
367 DstEncoding % 2 == 1)
368 return {RISCVII::LMUL_2, RISCV::VRM2RegClass, RISCV::VMV2R_V,
369 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
370 // Or we should do LMUL1 copying.
371 return {RISCVII::LMUL_1, RISCV::VRRegClass, RISCV::VMV1R_V,
372 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
373 }
374
375 // For forward copying, if source register encoding and destination register
376 // encoding are aligned to 8/4/2, we can do a LMUL8/4/2 copying.
377 if (I + 8 <= NumRegs && SrcEncoding % 8 == 0 && DstEncoding % 8 == 0)
378 return {RISCVII::LMUL_8, RISCV::VRM8RegClass, RISCV::VMV8R_V,
379 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
380 if (I + 4 <= NumRegs && SrcEncoding % 4 == 0 && DstEncoding % 4 == 0)
381 return {RISCVII::LMUL_4, RISCV::VRM4RegClass, RISCV::VMV4R_V,
382 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
383 if (I + 2 <= NumRegs && SrcEncoding % 2 == 0 && DstEncoding % 2 == 0)
384 return {RISCVII::LMUL_2, RISCV::VRM2RegClass, RISCV::VMV2R_V,
385 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
386 // Or we should do LMUL1 copying.
387 return {RISCVII::LMUL_1, RISCV::VRRegClass, RISCV::VMV1R_V,
388 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
389 };
390 auto FindRegWithEncoding = [TRI](const TargetRegisterClass &RegClass,
391 uint16_t Encoding) {
392 MCRegister Reg = RISCV::V0 + Encoding;
393 if (&RegClass == &RISCV::VRRegClass)
394 return Reg;
395 return TRI->getMatchingSuperReg(Reg, RISCV::sub_vrm1_0, &RegClass);
396 };
397 while (I != NumRegs) {
398 // For non-segment copying, we only do this once as the registers are always
399 // aligned.
400 // For segment copying, we may do this several times. If the registers are
401 // aligned to larger LMUL, we can eliminate some copyings.
402 auto [LMulCopied, RegClass, Opc, VVOpc, VIOpc] =
403 GetCopyInfo(SrcEncoding, DstEncoding);
404 auto [NumCopied, _] = RISCVVType::decodeVLMUL(LMulCopied);
405
407 if (LMul == LMulCopied &&
408 isConvertibleToVMV_V_V(STI, MBB, MBBI, DefMBBI, LMul)) {
409 Opc = VVOpc;
410 if (DefMBBI->getOpcode() == VIOpc)
411 Opc = VIOpc;
412 }
413
414 // Emit actual copying.
415 // For reversed copying, the encoding should be decreased.
416 MCRegister ActualSrcReg = FindRegWithEncoding(
417 RegClass, ReversedCopy ? (SrcEncoding - NumCopied + 1) : SrcEncoding);
418 MCRegister ActualDstReg = FindRegWithEncoding(
419 RegClass, ReversedCopy ? (DstEncoding - NumCopied + 1) : DstEncoding);
420
421 auto MIB = BuildMI(MBB, MBBI, DL, get(Opc), ActualDstReg);
422 bool UseVMV_V_I = RISCV::getRVVMCOpcode(Opc) == RISCV::VMV_V_I;
423 bool UseVMV = UseVMV_V_I || RISCV::getRVVMCOpcode(Opc) == RISCV::VMV_V_V;
424 if (UseVMV)
425 MIB.addReg(ActualDstReg, RegState::Undef);
426 if (UseVMV_V_I)
427 MIB = MIB.add(DefMBBI->getOperand(2));
428 else
429 MIB = MIB.addReg(ActualSrcReg, getKillRegState(KillSrc));
430 if (UseVMV) {
431 const MCInstrDesc &Desc = DefMBBI->getDesc();
432 MIB.add(DefMBBI->getOperand(RISCVII::getVLOpNum(Desc))); // AVL
433 unsigned Log2SEW =
434 DefMBBI->getOperand(RISCVII::getSEWOpNum(Desc)).getImm();
435 MIB.addImm(Log2SEW ? Log2SEW : 3); // SEW
436 MIB.addImm(0); // tu, mu
437 MIB.addReg(RISCV::VL, RegState::Implicit);
438 MIB.addReg(RISCV::VTYPE, RegState::Implicit);
439 }
440
441 // If we are copying reversely, we should decrease the encoding.
442 SrcEncoding += (ReversedCopy ? -NumCopied : NumCopied);
443 DstEncoding += (ReversedCopy ? -NumCopied : NumCopied);
444 I += NumCopied;
445 }
446}
447
450 const DebugLoc &DL, MCRegister DstReg,
451 MCRegister SrcReg, bool KillSrc,
452 bool RenamableDest, bool RenamableSrc) const {
454
455 if (RISCV::GPRRegClass.contains(DstReg, SrcReg)) {
456 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg)
457 .addReg(SrcReg,
458 getKillRegState(KillSrc) | getRenamableRegState(RenamableSrc))
459 .addImm(0);
460 return;
461 }
462
463 if (RISCV::GPRF16RegClass.contains(DstReg, SrcReg)) {
464 BuildMI(MBB, MBBI, DL, get(RISCV::PseudoMV_FPR16INX), DstReg)
465 .addReg(SrcReg,
466 getKillRegState(KillSrc) | getRenamableRegState(RenamableSrc));
467 return;
468 }
469
470 if (RISCV::GPRF32RegClass.contains(DstReg, SrcReg)) {
471 BuildMI(MBB, MBBI, DL, get(RISCV::PseudoMV_FPR32INX), DstReg)
472 .addReg(SrcReg,
473 getKillRegState(KillSrc) | getRenamableRegState(RenamableSrc));
474 return;
475 }
476
477 if (RISCV::GPRPairRegClass.contains(DstReg, SrcReg)) {
478 // Emit an ADDI for both parts of GPRPair.
479 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI),
480 TRI->getSubReg(DstReg, RISCV::sub_gpr_even))
481 .addReg(TRI->getSubReg(SrcReg, RISCV::sub_gpr_even),
482 getKillRegState(KillSrc))
483 .addImm(0);
484 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI),
485 TRI->getSubReg(DstReg, RISCV::sub_gpr_odd))
486 .addReg(TRI->getSubReg(SrcReg, RISCV::sub_gpr_odd),
487 getKillRegState(KillSrc))
488 .addImm(0);
489 return;
490 }
491
492 // Handle copy from csr
493 if (RISCV::VCSRRegClass.contains(SrcReg) &&
494 RISCV::GPRRegClass.contains(DstReg)) {
495 BuildMI(MBB, MBBI, DL, get(RISCV::CSRRS), DstReg)
496 .addImm(RISCVSysReg::lookupSysRegByName(TRI->getName(SrcReg))->Encoding)
497 .addReg(RISCV::X0);
498 return;
499 }
500
501 if (RISCV::FPR16RegClass.contains(DstReg, SrcReg)) {
502 unsigned Opc;
503 if (STI.hasStdExtZfh()) {
504 Opc = RISCV::FSGNJ_H;
505 } else {
506 assert(STI.hasStdExtF() &&
507 (STI.hasStdExtZfhmin() || STI.hasStdExtZfbfmin()) &&
508 "Unexpected extensions");
509 // Zfhmin/Zfbfmin doesn't have FSGNJ_H, replace FSGNJ_H with FSGNJ_S.
510 DstReg = TRI->getMatchingSuperReg(DstReg, RISCV::sub_16,
511 &RISCV::FPR32RegClass);
512 SrcReg = TRI->getMatchingSuperReg(SrcReg, RISCV::sub_16,
513 &RISCV::FPR32RegClass);
514 Opc = RISCV::FSGNJ_S;
515 }
516 BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
517 .addReg(SrcReg, getKillRegState(KillSrc))
518 .addReg(SrcReg, getKillRegState(KillSrc));
519 return;
520 }
521
522 if (RISCV::FPR32RegClass.contains(DstReg, SrcReg)) {
523 BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_S), DstReg)
524 .addReg(SrcReg, getKillRegState(KillSrc))
525 .addReg(SrcReg, getKillRegState(KillSrc));
526 return;
527 }
528
529 if (RISCV::FPR64RegClass.contains(DstReg, SrcReg)) {
530 BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_D), DstReg)
531 .addReg(SrcReg, getKillRegState(KillSrc))
532 .addReg(SrcReg, getKillRegState(KillSrc));
533 return;
534 }
535
536 if (RISCV::FPR32RegClass.contains(DstReg) &&
537 RISCV::GPRRegClass.contains(SrcReg)) {
538 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_W_X), DstReg)
539 .addReg(SrcReg, getKillRegState(KillSrc));
540 return;
541 }
542
543 if (RISCV::GPRRegClass.contains(DstReg) &&
544 RISCV::FPR32RegClass.contains(SrcReg)) {
545 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_X_W), DstReg)
546 .addReg(SrcReg, getKillRegState(KillSrc));
547 return;
548 }
549
550 if (RISCV::FPR64RegClass.contains(DstReg) &&
551 RISCV::GPRRegClass.contains(SrcReg)) {
552 assert(STI.getXLen() == 64 && "Unexpected GPR size");
553 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_D_X), DstReg)
554 .addReg(SrcReg, getKillRegState(KillSrc));
555 return;
556 }
557
558 if (RISCV::GPRRegClass.contains(DstReg) &&
559 RISCV::FPR64RegClass.contains(SrcReg)) {
560 assert(STI.getXLen() == 64 && "Unexpected GPR size");
561 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_X_D), DstReg)
562 .addReg(SrcReg, getKillRegState(KillSrc));
563 return;
564 }
565
566 // VR->VR copies.
567 static const TargetRegisterClass *RVVRegClasses[] = {
568 &RISCV::VRRegClass, &RISCV::VRM2RegClass, &RISCV::VRM4RegClass,
569 &RISCV::VRM8RegClass, &RISCV::VRN2M1RegClass, &RISCV::VRN2M2RegClass,
570 &RISCV::VRN2M4RegClass, &RISCV::VRN3M1RegClass, &RISCV::VRN3M2RegClass,
571 &RISCV::VRN4M1RegClass, &RISCV::VRN4M2RegClass, &RISCV::VRN5M1RegClass,
572 &RISCV::VRN6M1RegClass, &RISCV::VRN7M1RegClass, &RISCV::VRN8M1RegClass};
573 for (const auto &RegClass : RVVRegClasses) {
574 if (RegClass->contains(DstReg, SrcReg)) {
575 copyPhysRegVector(MBB, MBBI, DL, DstReg, SrcReg, KillSrc, RegClass);
576 return;
577 }
578 }
579
580 llvm_unreachable("Impossible reg-to-reg copy");
581}
582
585 Register SrcReg, bool IsKill, int FI,
586 const TargetRegisterClass *RC,
587 const TargetRegisterInfo *TRI,
588 Register VReg) const {
590 MachineFrameInfo &MFI = MF->getFrameInfo();
591
592 unsigned Opcode;
593 bool IsScalableVector = true;
594 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
595 Opcode = TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
596 RISCV::SW : RISCV::SD;
597 IsScalableVector = false;
598 } else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
599 Opcode = RISCV::SH_INX;
600 IsScalableVector = false;
601 } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
602 Opcode = RISCV::SW_INX;
603 IsScalableVector = false;
604 } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
605 Opcode = RISCV::PseudoRV32ZdinxSD;
606 IsScalableVector = false;
607 } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
608 Opcode = RISCV::FSH;
609 IsScalableVector = false;
610 } else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
611 Opcode = RISCV::FSW;
612 IsScalableVector = false;
613 } else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
614 Opcode = RISCV::FSD;
615 IsScalableVector = false;
616 } else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
617 Opcode = RISCV::VS1R_V;
618 } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
619 Opcode = RISCV::VS2R_V;
620 } else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
621 Opcode = RISCV::VS4R_V;
622 } else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
623 Opcode = RISCV::VS8R_V;
624 } else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
625 Opcode = RISCV::PseudoVSPILL2_M1;
626 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
627 Opcode = RISCV::PseudoVSPILL2_M2;
628 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
629 Opcode = RISCV::PseudoVSPILL2_M4;
630 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
631 Opcode = RISCV::PseudoVSPILL3_M1;
632 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
633 Opcode = RISCV::PseudoVSPILL3_M2;
634 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
635 Opcode = RISCV::PseudoVSPILL4_M1;
636 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
637 Opcode = RISCV::PseudoVSPILL4_M2;
638 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
639 Opcode = RISCV::PseudoVSPILL5_M1;
640 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
641 Opcode = RISCV::PseudoVSPILL6_M1;
642 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
643 Opcode = RISCV::PseudoVSPILL7_M1;
644 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
645 Opcode = RISCV::PseudoVSPILL8_M1;
646 else
647 llvm_unreachable("Can't store this register to stack slot");
648
649 if (IsScalableVector) {
653
655 BuildMI(MBB, I, DebugLoc(), get(Opcode))
656 .addReg(SrcReg, getKillRegState(IsKill))
657 .addFrameIndex(FI)
658 .addMemOperand(MMO);
659 } else {
662 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
663
664 BuildMI(MBB, I, DebugLoc(), get(Opcode))
665 .addReg(SrcReg, getKillRegState(IsKill))
666 .addFrameIndex(FI)
667 .addImm(0)
668 .addMemOperand(MMO);
669 }
670}
671
674 Register DstReg, int FI,
675 const TargetRegisterClass *RC,
676 const TargetRegisterInfo *TRI,
677 Register VReg) const {
679 MachineFrameInfo &MFI = MF->getFrameInfo();
680
681 unsigned Opcode;
682 bool IsScalableVector = true;
683 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
684 Opcode = TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
685 RISCV::LW : RISCV::LD;
686 IsScalableVector = false;
687 } else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
688 Opcode = RISCV::LH_INX;
689 IsScalableVector = false;
690 } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
691 Opcode = RISCV::LW_INX;
692 IsScalableVector = false;
693 } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
694 Opcode = RISCV::PseudoRV32ZdinxLD;
695 IsScalableVector = false;
696 } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
697 Opcode = RISCV::FLH;
698 IsScalableVector = false;
699 } else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
700 Opcode = RISCV::FLW;
701 IsScalableVector = false;
702 } else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
703 Opcode = RISCV::FLD;
704 IsScalableVector = false;
705 } else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
706 Opcode = RISCV::VL1RE8_V;
707 } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
708 Opcode = RISCV::VL2RE8_V;
709 } else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
710 Opcode = RISCV::VL4RE8_V;
711 } else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
712 Opcode = RISCV::VL8RE8_V;
713 } else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
714 Opcode = RISCV::PseudoVRELOAD2_M1;
715 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
716 Opcode = RISCV::PseudoVRELOAD2_M2;
717 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
718 Opcode = RISCV::PseudoVRELOAD2_M4;
719 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
720 Opcode = RISCV::PseudoVRELOAD3_M1;
721 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
722 Opcode = RISCV::PseudoVRELOAD3_M2;
723 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
724 Opcode = RISCV::PseudoVRELOAD4_M1;
725 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
726 Opcode = RISCV::PseudoVRELOAD4_M2;
727 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
728 Opcode = RISCV::PseudoVRELOAD5_M1;
729 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
730 Opcode = RISCV::PseudoVRELOAD6_M1;
731 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
732 Opcode = RISCV::PseudoVRELOAD7_M1;
733 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
734 Opcode = RISCV::PseudoVRELOAD8_M1;
735 else
736 llvm_unreachable("Can't load this register from stack slot");
737
738 if (IsScalableVector) {
742
744 BuildMI(MBB, I, DebugLoc(), get(Opcode), DstReg)
745 .addFrameIndex(FI)
746 .addMemOperand(MMO);
747 } else {
750 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
751
752 BuildMI(MBB, I, DebugLoc(), get(Opcode), DstReg)
753 .addFrameIndex(FI)
754 .addImm(0)
755 .addMemOperand(MMO);
756 }
757}
758
761 MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS,
762 VirtRegMap *VRM) const {
763 // The below optimizations narrow the load so they are only valid for little
764 // endian.
765 // TODO: Support big endian by adding an offset into the frame object?
766 if (MF.getDataLayout().isBigEndian())
767 return nullptr;
768
769 // Fold load from stack followed by sext.b/sext.h/sext.w/zext.b/zext.h/zext.w.
770 if (Ops.size() != 1 || Ops[0] != 1)
771 return nullptr;
772
773 unsigned LoadOpc;
774 switch (MI.getOpcode()) {
775 default:
776 if (RISCV::isSEXT_W(MI)) {
777 LoadOpc = RISCV::LW;
778 break;
779 }
780 if (RISCV::isZEXT_W(MI)) {
781 LoadOpc = RISCV::LWU;
782 break;
783 }
784 if (RISCV::isZEXT_B(MI)) {
785 LoadOpc = RISCV::LBU;
786 break;
787 }
788 if (RISCV::getRVVMCOpcode(MI.getOpcode()) == RISCV::VMV_X_S) {
789 unsigned Log2SEW =
790 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
791 if (STI.getXLen() < (1U << Log2SEW))
792 return nullptr;
793 switch (Log2SEW) {
794 case 3:
795 LoadOpc = RISCV::LB;
796 break;
797 case 4:
798 LoadOpc = RISCV::LH;
799 break;
800 case 5:
801 LoadOpc = RISCV::LW;
802 break;
803 case 6:
804 LoadOpc = RISCV::LD;
805 break;
806 default:
807 llvm_unreachable("Unexpected SEW");
808 }
809 break;
810 }
811 if (RISCV::getRVVMCOpcode(MI.getOpcode()) == RISCV::VFMV_F_S) {
812 unsigned Log2SEW =
813 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
814 switch (Log2SEW) {
815 case 4:
816 LoadOpc = RISCV::FLH;
817 break;
818 case 5:
819 LoadOpc = RISCV::FLW;
820 break;
821 case 6:
822 LoadOpc = RISCV::FLD;
823 break;
824 default:
825 llvm_unreachable("Unexpected SEW");
826 }
827 break;
828 }
829 return nullptr;
830 case RISCV::SEXT_H:
831 LoadOpc = RISCV::LH;
832 break;
833 case RISCV::SEXT_B:
834 LoadOpc = RISCV::LB;
835 break;
836 case RISCV::ZEXT_H_RV32:
837 case RISCV::ZEXT_H_RV64:
838 LoadOpc = RISCV::LHU;
839 break;
840 }
841
842 Register DstReg = MI.getOperand(0).getReg();
843 return BuildMI(*MI.getParent(), InsertPt, MI.getDebugLoc(), get(LoadOpc),
844 DstReg)
845 .addFrameIndex(FrameIndex)
846 .addImm(0);
847}
848
851 const DebugLoc &DL, Register DstReg, uint64_t Val,
852 MachineInstr::MIFlag Flag, bool DstRenamable,
853 bool DstIsDead) const {
854 Register SrcReg = RISCV::X0;
855
856 // For RV32, allow a sign or unsigned 32 bit value.
857 if (!STI.is64Bit() && !isInt<32>(Val)) {
858 // If have a uimm32 it will still fit in a register so we can allow it.
859 if (!isUInt<32>(Val))
860 report_fatal_error("Should only materialize 32-bit constants for RV32");
861
862 // Sign extend for generateInstSeq.
863 Val = SignExtend64<32>(Val);
864 }
865
867 assert(!Seq.empty());
868
869 bool SrcRenamable = false;
870 unsigned Num = 0;
871
872 for (const RISCVMatInt::Inst &Inst : Seq) {
873 bool LastItem = ++Num == Seq.size();
874 unsigned DstRegState = getDeadRegState(DstIsDead && LastItem) |
875 getRenamableRegState(DstRenamable);
876 unsigned SrcRegState = getKillRegState(SrcReg != RISCV::X0) |
877 getRenamableRegState(SrcRenamable);
878 switch (Inst.getOpndKind()) {
879 case RISCVMatInt::Imm:
880 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
881 .addReg(DstReg, RegState::Define | DstRegState)
882 .addImm(Inst.getImm())
883 .setMIFlag(Flag);
884 break;
886 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
887 .addReg(DstReg, RegState::Define | DstRegState)
888 .addReg(SrcReg, SrcRegState)
889 .addReg(RISCV::X0)
890 .setMIFlag(Flag);
891 break;
893 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
894 .addReg(DstReg, RegState::Define | DstRegState)
895 .addReg(SrcReg, SrcRegState)
896 .addReg(SrcReg, SrcRegState)
897 .setMIFlag(Flag);
898 break;
900 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
901 .addReg(DstReg, RegState::Define | DstRegState)
902 .addReg(SrcReg, SrcRegState)
903 .addImm(Inst.getImm())
904 .setMIFlag(Flag);
905 break;
906 }
907
908 // Only the first instruction has X0 as its source.
909 SrcReg = DstReg;
910 SrcRenamable = DstRenamable;
911 }
912}
913
915 switch (Opc) {
916 default:
918 case RISCV::CV_BEQIMM:
919 return RISCVCC::COND_EQ;
920 case RISCV::CV_BNEIMM:
921 return RISCVCC::COND_NE;
922 case RISCV::BEQ:
923 return RISCVCC::COND_EQ;
924 case RISCV::BNE:
925 return RISCVCC::COND_NE;
926 case RISCV::BLT:
927 return RISCVCC::COND_LT;
928 case RISCV::BGE:
929 return RISCVCC::COND_GE;
930 case RISCV::BLTU:
931 return RISCVCC::COND_LTU;
932 case RISCV::BGEU:
933 return RISCVCC::COND_GEU;
934 }
935}
936
937// The contents of values added to Cond are not examined outside of
938// RISCVInstrInfo, giving us flexibility in what to push to it. For RISCV, we
939// push BranchOpcode, Reg1, Reg2.
942 // Block ends with fall-through condbranch.
943 assert(LastInst.getDesc().isConditionalBranch() &&
944 "Unknown conditional branch");
945 Target = LastInst.getOperand(2).getMBB();
946 unsigned CC = getCondFromBranchOpc(LastInst.getOpcode());
948 Cond.push_back(LastInst.getOperand(0));
949 Cond.push_back(LastInst.getOperand(1));
950}
951
953 switch (CC) {
954 default:
955 llvm_unreachable("Unknown condition code!");
956 case RISCVCC::COND_EQ:
957 return Imm ? RISCV::CV_BEQIMM : RISCV::BEQ;
958 case RISCVCC::COND_NE:
959 return Imm ? RISCV::CV_BNEIMM : RISCV::BNE;
960 case RISCVCC::COND_LT:
961 return RISCV::BLT;
962 case RISCVCC::COND_GE:
963 return RISCV::BGE;
965 return RISCV::BLTU;
967 return RISCV::BGEU;
968 }
969}
970
972 bool Imm) const {
973 return get(RISCVCC::getBrCond(CC, Imm));
974}
975
977 switch (CC) {
978 default:
979 llvm_unreachable("Unrecognized conditional branch");
980 case RISCVCC::COND_EQ:
981 return RISCVCC::COND_NE;
982 case RISCVCC::COND_NE:
983 return RISCVCC::COND_EQ;
984 case RISCVCC::COND_LT:
985 return RISCVCC::COND_GE;
986 case RISCVCC::COND_GE:
987 return RISCVCC::COND_LT;
989 return RISCVCC::COND_GEU;
991 return RISCVCC::COND_LTU;
992 }
993}
994
997 MachineBasicBlock *&FBB,
999 bool AllowModify) const {
1000 TBB = FBB = nullptr;
1001 Cond.clear();
1002
1003 // If the block has no terminators, it just falls into the block after it.
1005 if (I == MBB.end() || !isUnpredicatedTerminator(*I))
1006 return false;
1007
1008 // Count the number of terminators and find the first unconditional or
1009 // indirect branch.
1010 MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
1011 int NumTerminators = 0;
1012 for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
1013 J++) {
1014 NumTerminators++;
1015 if (J->getDesc().isUnconditionalBranch() ||
1016 J->getDesc().isIndirectBranch()) {
1017 FirstUncondOrIndirectBr = J.getReverse();
1018 }
1019 }
1020
1021 // If AllowModify is true, we can erase any terminators after
1022 // FirstUncondOrIndirectBR.
1023 if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
1024 while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
1025 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
1026 NumTerminators--;
1027 }
1028 I = FirstUncondOrIndirectBr;
1029 }
1030
1031 // We can't handle blocks that end in an indirect branch.
1032 if (I->getDesc().isIndirectBranch())
1033 return true;
1034
1035 // We can't handle Generic branch opcodes from Global ISel.
1036 if (I->isPreISelOpcode())
1037 return true;
1038
1039 // We can't handle blocks with more than 2 terminators.
1040 if (NumTerminators > 2)
1041 return true;
1042
1043 // Handle a single unconditional branch.
1044 if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
1046 return false;
1047 }
1048
1049 // Handle a single conditional branch.
1050 if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
1052 return false;
1053 }
1054
1055 // Handle a conditional branch followed by an unconditional branch.
1056 if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
1057 I->getDesc().isUnconditionalBranch()) {
1058 parseCondBranch(*std::prev(I), TBB, Cond);
1059 FBB = getBranchDestBlock(*I);
1060 return false;
1061 }
1062
1063 // Otherwise, we can't handle this.
1064 return true;
1065}
1066
1068 int *BytesRemoved) const {
1069 if (BytesRemoved)
1070 *BytesRemoved = 0;
1072 if (I == MBB.end())
1073 return 0;
1074
1075 if (!I->getDesc().isUnconditionalBranch() &&
1076 !I->getDesc().isConditionalBranch())
1077 return 0;
1078
1079 // Remove the branch.
1080 if (BytesRemoved)
1081 *BytesRemoved += getInstSizeInBytes(*I);
1082 I->eraseFromParent();
1083
1084 I = MBB.end();
1085
1086 if (I == MBB.begin())
1087 return 1;
1088 --I;
1089 if (!I->getDesc().isConditionalBranch())
1090 return 1;
1091
1092 // Remove the branch.
1093 if (BytesRemoved)
1094 *BytesRemoved += getInstSizeInBytes(*I);
1095 I->eraseFromParent();
1096 return 2;
1097}
1098
1099// Inserts a branch into the end of the specific MachineBasicBlock, returning
1100// the number of instructions inserted.
1103 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
1104 if (BytesAdded)
1105 *BytesAdded = 0;
1106
1107 // Shouldn't be a fall through.
1108 assert(TBB && "insertBranch must not be told to insert a fallthrough");
1109 assert((Cond.size() == 3 || Cond.size() == 0) &&
1110 "RISC-V branch conditions have two components!");
1111
1112 // Unconditional branch.
1113 if (Cond.empty()) {
1114 MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(TBB);
1115 if (BytesAdded)
1116 *BytesAdded += getInstSizeInBytes(MI);
1117 return 1;
1118 }
1119
1120 // Either a one or two-way conditional branch.
1121 auto CC = static_cast<RISCVCC::CondCode>(Cond[0].getImm());
1122 MachineInstr &CondMI = *BuildMI(&MBB, DL, getBrCond(CC, Cond[2].isImm()))
1123 .add(Cond[1])
1124 .add(Cond[2])
1125 .addMBB(TBB);
1126 if (BytesAdded)
1127 *BytesAdded += getInstSizeInBytes(CondMI);
1128
1129 // One-way conditional branch.
1130 if (!FBB)
1131 return 1;
1132
1133 // Two-way conditional branch.
1134 MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(FBB);
1135 if (BytesAdded)
1136 *BytesAdded += getInstSizeInBytes(MI);
1137 return 2;
1138}
1139
1141 MachineBasicBlock &DestBB,
1142 MachineBasicBlock &RestoreBB,
1143 const DebugLoc &DL, int64_t BrOffset,
1144 RegScavenger *RS) const {
1145 assert(RS && "RegScavenger required for long branching");
1146 assert(MBB.empty() &&
1147 "new block should be inserted for expanding unconditional branch");
1148 assert(MBB.pred_size() == 1);
1149 assert(RestoreBB.empty() &&
1150 "restore block should be inserted for restoring clobbered registers");
1151
1156
1157 if (!isInt<32>(BrOffset))
1159 "Branch offsets outside of the signed 32-bit range not supported");
1160
1161 // FIXME: A virtual register must be used initially, as the register
1162 // scavenger won't work with empty blocks (SIInstrInfo::insertIndirectBranch
1163 // uses the same workaround).
1164 Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRJALRRegClass);
1165 auto II = MBB.end();
1166 // We may also update the jump target to RestoreBB later.
1167 MachineInstr &MI = *BuildMI(MBB, II, DL, get(RISCV::PseudoJump))
1168 .addReg(ScratchReg, RegState::Define | RegState::Dead)
1169 .addMBB(&DestBB, RISCVII::MO_CALL);
1170
1172 Register TmpGPR =
1173 RS->scavengeRegisterBackwards(RISCV::GPRRegClass, MI.getIterator(),
1174 /*RestoreAfter=*/false, /*SpAdj=*/0,
1175 /*AllowSpill=*/false);
1176 if (TmpGPR != RISCV::NoRegister)
1177 RS->setRegUsed(TmpGPR);
1178 else {
1179 // The case when there is no scavenged register needs special handling.
1180
1181 // Pick s11 because it doesn't make a difference.
1182 TmpGPR = RISCV::X27;
1183
1184 int FrameIndex = RVFI->getBranchRelaxationScratchFrameIndex();
1185 if (FrameIndex == -1)
1186 report_fatal_error("underestimated function size");
1187
1188 storeRegToStackSlot(MBB, MI, TmpGPR, /*IsKill=*/true, FrameIndex,
1189 &RISCV::GPRRegClass, TRI, Register());
1190 TRI->eliminateFrameIndex(std::prev(MI.getIterator()),
1191 /*SpAdj=*/0, /*FIOperandNum=*/1);
1192
1193 MI.getOperand(1).setMBB(&RestoreBB);
1194
1195 loadRegFromStackSlot(RestoreBB, RestoreBB.end(), TmpGPR, FrameIndex,
1196 &RISCV::GPRRegClass, TRI, Register());
1197 TRI->eliminateFrameIndex(RestoreBB.back(),
1198 /*SpAdj=*/0, /*FIOperandNum=*/1);
1199 }
1200
1201 MRI.replaceRegWith(ScratchReg, TmpGPR);
1202 MRI.clearVirtRegs();
1203}
1204
1207 assert((Cond.size() == 3) && "Invalid branch condition!");
1208 auto CC = static_cast<RISCVCC::CondCode>(Cond[0].getImm());
1210 return false;
1211}
1212
1214 MachineBasicBlock *MBB = MI.getParent();
1216
1217 MachineBasicBlock *TBB, *FBB;
1219 if (analyzeBranch(*MBB, TBB, FBB, Cond, /*AllowModify=*/false))
1220 return false;
1221
1222 RISCVCC::CondCode CC = static_cast<RISCVCC::CondCode>(Cond[0].getImm());
1224
1226 return false;
1227
1228 // For two constants C0 and C1 from
1229 // ```
1230 // li Y, C0
1231 // li Z, C1
1232 // ```
1233 // 1. if C1 = C0 + 1
1234 // we can turn:
1235 // (a) blt Y, X -> bge X, Z
1236 // (b) bge Y, X -> blt X, Z
1237 //
1238 // 2. if C1 = C0 - 1
1239 // we can turn:
1240 // (a) blt X, Y -> bge Z, X
1241 // (b) bge X, Y -> blt Z, X
1242 //
1243 // To make sure this optimization is really beneficial, we only
1244 // optimize for cases where Y had only one use (i.e. only used by the branch).
1245
1246 // Right now we only care about LI (i.e. ADDI x0, imm)
1247 auto isLoadImm = [](const MachineInstr *MI, int64_t &Imm) -> bool {
1248 if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
1249 MI->getOperand(1).getReg() == RISCV::X0) {
1250 Imm = MI->getOperand(2).getImm();
1251 return true;
1252 }
1253 return false;
1254 };
1255 // Either a load from immediate instruction or X0.
1256 auto isFromLoadImm = [&](const MachineOperand &Op, int64_t &Imm) -> bool {
1257 if (!Op.isReg())
1258 return false;
1259 Register Reg = Op.getReg();
1260 return Reg.isVirtual() && isLoadImm(MRI.getVRegDef(Reg), Imm);
1261 };
1262
1263 MachineOperand &LHS = MI.getOperand(0);
1264 MachineOperand &RHS = MI.getOperand(1);
1265 // Try to find the register for constant Z; return
1266 // invalid register otherwise.
1267 auto searchConst = [&](int64_t C1) -> Register {
1269 auto DefC1 = std::find_if(++II, E, [&](const MachineInstr &I) -> bool {
1270 int64_t Imm;
1271 return isLoadImm(&I, Imm) && Imm == C1 &&
1272 I.getOperand(0).getReg().isVirtual();
1273 });
1274 if (DefC1 != E)
1275 return DefC1->getOperand(0).getReg();
1276
1277 return Register();
1278 };
1279
1280 bool Modify = false;
1281 int64_t C0;
1282 if (isFromLoadImm(LHS, C0) && MRI.hasOneUse(LHS.getReg())) {
1283 // Might be case 1.
1284 // Signed integer overflow is UB. (UINT64_MAX is bigger so we don't need
1285 // to worry about unsigned overflow here)
1286 if (C0 < INT64_MAX)
1287 if (Register RegZ = searchConst(C0 + 1)) {
1289 Cond[1] = MachineOperand::CreateReg(RHS.getReg(), /*isDef=*/false);
1290 Cond[2] = MachineOperand::CreateReg(RegZ, /*isDef=*/false);
1291 // We might extend the live range of Z, clear its kill flag to
1292 // account for this.
1293 MRI.clearKillFlags(RegZ);
1294 Modify = true;
1295 }
1296 } else if (isFromLoadImm(RHS, C0) && MRI.hasOneUse(RHS.getReg())) {
1297 // Might be case 2.
1298 // For unsigned cases, we don't want C1 to wrap back to UINT64_MAX
1299 // when C0 is zero.
1300 if ((CC == RISCVCC::COND_GE || CC == RISCVCC::COND_LT) || C0)
1301 if (Register RegZ = searchConst(C0 - 1)) {
1303 Cond[1] = MachineOperand::CreateReg(RegZ, /*isDef=*/false);
1304 Cond[2] = MachineOperand::CreateReg(LHS.getReg(), /*isDef=*/false);
1305 // We might extend the live range of Z, clear its kill flag to
1306 // account for this.
1307 MRI.clearKillFlags(RegZ);
1308 Modify = true;
1309 }
1310 }
1311
1312 if (!Modify)
1313 return false;
1314
1315 // Build the new branch and remove the old one.
1316 BuildMI(*MBB, MI, MI.getDebugLoc(),
1317 getBrCond(static_cast<RISCVCC::CondCode>(Cond[0].getImm())))
1318 .add(Cond[1])
1319 .add(Cond[2])
1320 .addMBB(TBB);
1321 MI.eraseFromParent();
1322
1323 return true;
1324}
1325
1328 assert(MI.getDesc().isBranch() && "Unexpected opcode!");
1329 // The branch target is always the last operand.
1330 int NumOp = MI.getNumExplicitOperands();
1331 return MI.getOperand(NumOp - 1).getMBB();
1332}
1333
1335 int64_t BrOffset) const {
1336 unsigned XLen = STI.getXLen();
1337 // Ideally we could determine the supported branch offset from the
1338 // RISCVII::FormMask, but this can't be used for Pseudo instructions like
1339 // PseudoBR.
1340 switch (BranchOp) {
1341 default:
1342 llvm_unreachable("Unexpected opcode!");
1343 case RISCV::BEQ:
1344 case RISCV::BNE:
1345 case RISCV::BLT:
1346 case RISCV::BGE:
1347 case RISCV::BLTU:
1348 case RISCV::BGEU:
1349 case RISCV::CV_BEQIMM:
1350 case RISCV::CV_BNEIMM:
1351 return isIntN(13, BrOffset);
1352 case RISCV::JAL:
1353 case RISCV::PseudoBR:
1354 return isIntN(21, BrOffset);
1355 case RISCV::PseudoJump:
1356 return isIntN(32, SignExtend64(BrOffset + 0x800, XLen));
1357 }
1358}
1359
1360// If the operation has a predicated pseudo instruction, return the pseudo
1361// instruction opcode. Otherwise, return RISCV::INSTRUCTION_LIST_END.
1362// TODO: Support more operations.
1363unsigned getPredicatedOpcode(unsigned Opcode) {
1364 switch (Opcode) {
1365 case RISCV::ADD: return RISCV::PseudoCCADD; break;
1366 case RISCV::SUB: return RISCV::PseudoCCSUB; break;
1367 case RISCV::SLL: return RISCV::PseudoCCSLL; break;
1368 case RISCV::SRL: return RISCV::PseudoCCSRL; break;
1369 case RISCV::SRA: return RISCV::PseudoCCSRA; break;
1370 case RISCV::AND: return RISCV::PseudoCCAND; break;
1371 case RISCV::OR: return RISCV::PseudoCCOR; break;
1372 case RISCV::XOR: return RISCV::PseudoCCXOR; break;
1373
1374 case RISCV::ADDI: return RISCV::PseudoCCADDI; break;
1375 case RISCV::SLLI: return RISCV::PseudoCCSLLI; break;
1376 case RISCV::SRLI: return RISCV::PseudoCCSRLI; break;
1377 case RISCV::SRAI: return RISCV::PseudoCCSRAI; break;
1378 case RISCV::ANDI: return RISCV::PseudoCCANDI; break;
1379 case RISCV::ORI: return RISCV::PseudoCCORI; break;
1380 case RISCV::XORI: return RISCV::PseudoCCXORI; break;
1381
1382 case RISCV::ADDW: return RISCV::PseudoCCADDW; break;
1383 case RISCV::SUBW: return RISCV::PseudoCCSUBW; break;
1384 case RISCV::SLLW: return RISCV::PseudoCCSLLW; break;
1385 case RISCV::SRLW: return RISCV::PseudoCCSRLW; break;
1386 case RISCV::SRAW: return RISCV::PseudoCCSRAW; break;
1387
1388 case RISCV::ADDIW: return RISCV::PseudoCCADDIW; break;
1389 case RISCV::SLLIW: return RISCV::PseudoCCSLLIW; break;
1390 case RISCV::SRLIW: return RISCV::PseudoCCSRLIW; break;
1391 case RISCV::SRAIW: return RISCV::PseudoCCSRAIW; break;
1392
1393 case RISCV::ANDN: return RISCV::PseudoCCANDN; break;
1394 case RISCV::ORN: return RISCV::PseudoCCORN; break;
1395 case RISCV::XNOR: return RISCV::PseudoCCXNOR; break;
1396 }
1397
1398 return RISCV::INSTRUCTION_LIST_END;
1399}
1400
1401/// Identify instructions that can be folded into a CCMOV instruction, and
1402/// return the defining instruction.
1404 const MachineRegisterInfo &MRI,
1405 const TargetInstrInfo *TII) {
1406 if (!Reg.isVirtual())
1407 return nullptr;
1408 if (!MRI.hasOneNonDBGUse(Reg))
1409 return nullptr;
1410 MachineInstr *MI = MRI.getVRegDef(Reg);
1411 if (!MI)
1412 return nullptr;
1413 // Check if MI can be predicated and folded into the CCMOV.
1414 if (getPredicatedOpcode(MI->getOpcode()) == RISCV::INSTRUCTION_LIST_END)
1415 return nullptr;
1416 // Don't predicate li idiom.
1417 if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
1418 MI->getOperand(1).getReg() == RISCV::X0)
1419 return nullptr;
1420 // Check if MI has any other defs or physreg uses.
1421 for (const MachineOperand &MO : llvm::drop_begin(MI->operands())) {
1422 // Reject frame index operands, PEI can't handle the predicated pseudos.
1423 if (MO.isFI() || MO.isCPI() || MO.isJTI())
1424 return nullptr;
1425 if (!MO.isReg())
1426 continue;
1427 // MI can't have any tied operands, that would conflict with predication.
1428 if (MO.isTied())
1429 return nullptr;
1430 if (MO.isDef())
1431 return nullptr;
1432 // Allow constant physregs.
1433 if (MO.getReg().isPhysical() && !MRI.isConstantPhysReg(MO.getReg()))
1434 return nullptr;
1435 }
1436 bool DontMoveAcrossStores = true;
1437 if (!MI->isSafeToMove(DontMoveAcrossStores))
1438 return nullptr;
1439 return MI;
1440}
1441
1444 unsigned &TrueOp, unsigned &FalseOp,
1445 bool &Optimizable) const {
1446 assert(MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1447 "Unknown select instruction");
1448 // CCMOV operands:
1449 // 0: Def.
1450 // 1: LHS of compare.
1451 // 2: RHS of compare.
1452 // 3: Condition code.
1453 // 4: False use.
1454 // 5: True use.
1455 TrueOp = 5;
1456 FalseOp = 4;
1457 Cond.push_back(MI.getOperand(1));
1458 Cond.push_back(MI.getOperand(2));
1459 Cond.push_back(MI.getOperand(3));
1460 // We can only fold when we support short forward branch opt.
1461 Optimizable = STI.hasShortForwardBranchOpt();
1462 return false;
1463}
1464
1468 bool PreferFalse) const {
1469 assert(MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1470 "Unknown select instruction");
1471 if (!STI.hasShortForwardBranchOpt())
1472 return nullptr;
1473
1474 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
1476 canFoldAsPredicatedOp(MI.getOperand(5).getReg(), MRI, this);
1477 bool Invert = !DefMI;
1478 if (!DefMI)
1479 DefMI = canFoldAsPredicatedOp(MI.getOperand(4).getReg(), MRI, this);
1480 if (!DefMI)
1481 return nullptr;
1482
1483 // Find new register class to use.
1484 MachineOperand FalseReg = MI.getOperand(Invert ? 5 : 4);
1485 Register DestReg = MI.getOperand(0).getReg();
1486 const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
1487 if (!MRI.constrainRegClass(DestReg, PreviousClass))
1488 return nullptr;
1489
1490 unsigned PredOpc = getPredicatedOpcode(DefMI->getOpcode());
1491 assert(PredOpc != RISCV::INSTRUCTION_LIST_END && "Unexpected opcode!");
1492
1493 // Create a new predicated version of DefMI.
1494 MachineInstrBuilder NewMI =
1495 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(PredOpc), DestReg);
1496
1497 // Copy the condition portion.
1498 NewMI.add(MI.getOperand(1));
1499 NewMI.add(MI.getOperand(2));
1500
1501 // Add condition code, inverting if necessary.
1502 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
1503 if (Invert)
1505 NewMI.addImm(CC);
1506
1507 // Copy the false register.
1508 NewMI.add(FalseReg);
1509
1510 // Copy all the DefMI operands.
1511 const MCInstrDesc &DefDesc = DefMI->getDesc();
1512 for (unsigned i = 1, e = DefDesc.getNumOperands(); i != e; ++i)
1513 NewMI.add(DefMI->getOperand(i));
1514
1515 // Update SeenMIs set: register newly created MI and erase removed DefMI.
1516 SeenMIs.insert(NewMI);
1517 SeenMIs.erase(DefMI);
1518
1519 // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
1520 // DefMI would be invalid when tranferred inside the loop. Checking for a
1521 // loop is expensive, but at least remove kill flags if they are in different
1522 // BBs.
1523 if (DefMI->getParent() != MI.getParent())
1524 NewMI->clearKillInfo();
1525
1526 // The caller will erase MI, but not DefMI.
1528 return NewMI;
1529}
1530
1532 if (MI.isMetaInstruction())
1533 return 0;
1534
1535 unsigned Opcode = MI.getOpcode();
1536
1537 if (Opcode == TargetOpcode::INLINEASM ||
1538 Opcode == TargetOpcode::INLINEASM_BR) {
1539 const MachineFunction &MF = *MI.getParent()->getParent();
1540 return getInlineAsmLength(MI.getOperand(0).getSymbolName(),
1541 *MF.getTarget().getMCAsmInfo());
1542 }
1543
1544 if (!MI.memoperands_empty()) {
1545 MachineMemOperand *MMO = *(MI.memoperands_begin());
1546 if (STI.hasStdExtZihintntl() && MMO->isNonTemporal()) {
1547 if (STI.hasStdExtCOrZca() && STI.enableRVCHintInstrs()) {
1548 if (isCompressibleInst(MI, STI))
1549 return 4; // c.ntl.all + c.load/c.store
1550 return 6; // c.ntl.all + load/store
1551 }
1552 return 8; // ntl.all + load/store
1553 }
1554 }
1555
1556 if (Opcode == TargetOpcode::BUNDLE)
1557 return getInstBundleLength(MI);
1558
1559 if (MI.getParent() && MI.getParent()->getParent()) {
1560 if (isCompressibleInst(MI, STI))
1561 return 2;
1562 }
1563
1564 switch (Opcode) {
1565 case RISCV::PseudoMV_FPR16INX:
1566 case RISCV::PseudoMV_FPR32INX:
1567 // MV is always compressible to either c.mv or c.li rd, 0.
1568 return STI.hasStdExtCOrZca() ? 2 : 4;
1569 case TargetOpcode::STACKMAP:
1570 // The upper bound for a stackmap intrinsic is the full length of its shadow
1572 case TargetOpcode::PATCHPOINT:
1573 // The size of the patchpoint intrinsic is the number of bytes requested
1575 case TargetOpcode::STATEPOINT: {
1576 // The size of the statepoint intrinsic is the number of bytes requested
1577 unsigned NumBytes = StatepointOpers(&MI).getNumPatchBytes();
1578 // No patch bytes means at most a PseudoCall is emitted
1579 return std::max(NumBytes, 8U);
1580 }
1581 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
1582 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1583 case TargetOpcode::PATCHABLE_TAIL_CALL: {
1584 const MachineFunction &MF = *MI.getParent()->getParent();
1585 const Function &F = MF.getFunction();
1586 if (Opcode == TargetOpcode::PATCHABLE_FUNCTION_ENTER &&
1587 F.hasFnAttribute("patchable-function-entry")) {
1588 unsigned Num;
1589 if (F.getFnAttribute("patchable-function-entry")
1590 .getValueAsString()
1591 .getAsInteger(10, Num))
1592 return get(Opcode).getSize();
1593
1594 // Number of C.NOP or NOP
1595 return (STI.hasStdExtCOrZca() ? 2 : 4) * Num;
1596 }
1597 // XRay uses C.JAL + 21 or 33 C.NOP for each sled in RV32 and RV64,
1598 // respectively.
1599 return STI.is64Bit() ? 68 : 44;
1600 }
1601 default:
1602 return get(Opcode).getSize();
1603 }
1604}
1605
1606unsigned RISCVInstrInfo::getInstBundleLength(const MachineInstr &MI) const {
1607 unsigned Size = 0;
1609 MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
1610 while (++I != E && I->isInsideBundle()) {
1611 assert(!I->isBundle() && "No nested bundle!");
1613 }
1614 return Size;
1615}
1616
1618 const unsigned Opcode = MI.getOpcode();
1619 switch (Opcode) {
1620 default:
1621 break;
1622 case RISCV::FSGNJ_D:
1623 case RISCV::FSGNJ_S:
1624 case RISCV::FSGNJ_H:
1625 case RISCV::FSGNJ_D_INX:
1626 case RISCV::FSGNJ_D_IN32X:
1627 case RISCV::FSGNJ_S_INX:
1628 case RISCV::FSGNJ_H_INX:
1629 // The canonical floating-point move is fsgnj rd, rs, rs.
1630 return MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
1631 MI.getOperand(1).getReg() == MI.getOperand(2).getReg();
1632 case RISCV::ADDI:
1633 case RISCV::ORI:
1634 case RISCV::XORI:
1635 return (MI.getOperand(1).isReg() &&
1636 MI.getOperand(1).getReg() == RISCV::X0) ||
1637 (MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0);
1638 }
1639 return MI.isAsCheapAsAMove();
1640}
1641
1642std::optional<DestSourcePair>
1644 if (MI.isMoveReg())
1645 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1646 switch (MI.getOpcode()) {
1647 default:
1648 break;
1649 case RISCV::ADDI:
1650 // Operand 1 can be a frameindex but callers expect registers
1651 if (MI.getOperand(1).isReg() && MI.getOperand(2).isImm() &&
1652 MI.getOperand(2).getImm() == 0)
1653 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1654 break;
1655 case RISCV::FSGNJ_D:
1656 case RISCV::FSGNJ_S:
1657 case RISCV::FSGNJ_H:
1658 case RISCV::FSGNJ_D_INX:
1659 case RISCV::FSGNJ_D_IN32X:
1660 case RISCV::FSGNJ_S_INX:
1661 case RISCV::FSGNJ_H_INX:
1662 // The canonical floating-point move is fsgnj rd, rs, rs.
1663 if (MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
1664 MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
1665 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1666 break;
1667 }
1668 return std::nullopt;
1669}
1670
1672 if (ForceMachineCombinerStrategy.getNumOccurrences() == 0) {
1673 // The option is unused. Choose Local strategy only for in-order cores. When
1674 // scheduling model is unspecified, use MinInstrCount strategy as more
1675 // generic one.
1676 const auto &SchedModel = STI.getSchedModel();
1677 return (!SchedModel.hasInstrSchedModel() || SchedModel.isOutOfOrder())
1680 }
1681 // The strategy was forced by the option.
1683}
1684
1686 MachineInstr &Root, unsigned &Pattern,
1687 SmallVectorImpl<MachineInstr *> &InsInstrs) const {
1688 int16_t FrmOpIdx =
1689 RISCV::getNamedOperandIdx(Root.getOpcode(), RISCV::OpName::frm);
1690 if (FrmOpIdx < 0) {
1691 assert(all_of(InsInstrs,
1692 [](MachineInstr *MI) {
1693 return RISCV::getNamedOperandIdx(MI->getOpcode(),
1694 RISCV::OpName::frm) < 0;
1695 }) &&
1696 "New instructions require FRM whereas the old one does not have it");
1697 return;
1698 }
1699
1700 const MachineOperand &FRM = Root.getOperand(FrmOpIdx);
1701 MachineFunction &MF = *Root.getMF();
1702
1703 for (auto *NewMI : InsInstrs) {
1704 // We'd already added the FRM operand.
1705 if (static_cast<unsigned>(RISCV::getNamedOperandIdx(
1706 NewMI->getOpcode(), RISCV::OpName::frm)) != NewMI->getNumOperands())
1707 continue;
1708 MachineInstrBuilder MIB(MF, NewMI);
1709 MIB.add(FRM);
1710 if (FRM.getImm() == RISCVFPRndMode::DYN)
1711 MIB.addUse(RISCV::FRM, RegState::Implicit);
1712 }
1713}
1714
1715static bool isFADD(unsigned Opc) {
1716 switch (Opc) {
1717 default:
1718 return false;
1719 case RISCV::FADD_H:
1720 case RISCV::FADD_S:
1721 case RISCV::FADD_D:
1722 return true;
1723 }
1724}
1725
1726static bool isFSUB(unsigned Opc) {
1727 switch (Opc) {
1728 default:
1729 return false;
1730 case RISCV::FSUB_H:
1731 case RISCV::FSUB_S:
1732 case RISCV::FSUB_D:
1733 return true;
1734 }
1735}
1736
1737static bool isFMUL(unsigned Opc) {
1738 switch (Opc) {
1739 default:
1740 return false;
1741 case RISCV::FMUL_H:
1742 case RISCV::FMUL_S:
1743 case RISCV::FMUL_D:
1744 return true;
1745 }
1746}
1747
1748bool RISCVInstrInfo::isVectorAssociativeAndCommutative(const MachineInstr &Inst,
1749 bool Invert) const {
1750#define OPCODE_LMUL_CASE(OPC) \
1751 case RISCV::OPC##_M1: \
1752 case RISCV::OPC##_M2: \
1753 case RISCV::OPC##_M4: \
1754 case RISCV::OPC##_M8: \
1755 case RISCV::OPC##_MF2: \
1756 case RISCV::OPC##_MF4: \
1757 case RISCV::OPC##_MF8
1758
1759#define OPCODE_LMUL_MASK_CASE(OPC) \
1760 case RISCV::OPC##_M1_MASK: \
1761 case RISCV::OPC##_M2_MASK: \
1762 case RISCV::OPC##_M4_MASK: \
1763 case RISCV::OPC##_M8_MASK: \
1764 case RISCV::OPC##_MF2_MASK: \
1765 case RISCV::OPC##_MF4_MASK: \
1766 case RISCV::OPC##_MF8_MASK
1767
1768 unsigned Opcode = Inst.getOpcode();
1769 if (Invert) {
1770 if (auto InvOpcode = getInverseOpcode(Opcode))
1771 Opcode = *InvOpcode;
1772 else
1773 return false;
1774 }
1775
1776 // clang-format off
1777 switch (Opcode) {
1778 default:
1779 return false;
1780 OPCODE_LMUL_CASE(PseudoVADD_VV):
1781 OPCODE_LMUL_MASK_CASE(PseudoVADD_VV):
1782 OPCODE_LMUL_CASE(PseudoVMUL_VV):
1783 OPCODE_LMUL_MASK_CASE(PseudoVMUL_VV):
1784 return true;
1785 }
1786 // clang-format on
1787
1788#undef OPCODE_LMUL_MASK_CASE
1789#undef OPCODE_LMUL_CASE
1790}
1791
1792bool RISCVInstrInfo::areRVVInstsReassociable(const MachineInstr &Root,
1793 const MachineInstr &Prev) const {
1794 if (!areOpcodesEqualOrInverse(Root.getOpcode(), Prev.getOpcode()))
1795 return false;
1796
1797 assert(Root.getMF() == Prev.getMF());
1798 const MachineRegisterInfo *MRI = &Root.getMF()->getRegInfo();
1799 const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
1800
1801 // Make sure vtype operands are also the same.
1802 const MCInstrDesc &Desc = get(Root.getOpcode());
1803 const uint64_t TSFlags = Desc.TSFlags;
1804
1805 auto checkImmOperand = [&](unsigned OpIdx) {
1806 return Root.getOperand(OpIdx).getImm() == Prev.getOperand(OpIdx).getImm();
1807 };
1808
1809 auto checkRegOperand = [&](unsigned OpIdx) {
1810 return Root.getOperand(OpIdx).getReg() == Prev.getOperand(OpIdx).getReg();
1811 };
1812
1813 // PassThru
1814 // TODO: Potentially we can loosen the condition to consider Root to be
1815 // associable with Prev if Root has NoReg as passthru. In which case we
1816 // also need to loosen the condition on vector policies between these.
1817 if (!checkRegOperand(1))
1818 return false;
1819
1820 // SEW
1821 if (RISCVII::hasSEWOp(TSFlags) &&
1822 !checkImmOperand(RISCVII::getSEWOpNum(Desc)))
1823 return false;
1824
1825 // Mask
1826 if (RISCVII::usesMaskPolicy(TSFlags)) {
1827 const MachineBasicBlock *MBB = Root.getParent();
1830 Register MI1VReg;
1831
1832 bool SeenMI2 = false;
1833 for (auto End = MBB->rend(), It = It1; It != End; ++It) {
1834 if (It == It2) {
1835 SeenMI2 = true;
1836 if (!MI1VReg.isValid())
1837 // There is no V0 def between Root and Prev; they're sharing the
1838 // same V0.
1839 break;
1840 }
1841
1842 if (It->modifiesRegister(RISCV::V0, TRI)) {
1843 Register SrcReg = It->getOperand(1).getReg();
1844 // If it's not VReg it'll be more difficult to track its defs, so
1845 // bailing out here just to be safe.
1846 if (!SrcReg.isVirtual())
1847 return false;
1848
1849 if (!MI1VReg.isValid()) {
1850 // This is the V0 def for Root.
1851 MI1VReg = SrcReg;
1852 continue;
1853 }
1854
1855 // Some random mask updates.
1856 if (!SeenMI2)
1857 continue;
1858
1859 // This is the V0 def for Prev; check if it's the same as that of
1860 // Root.
1861 if (MI1VReg != SrcReg)
1862 return false;
1863 else
1864 break;
1865 }
1866 }
1867
1868 // If we haven't encountered Prev, it's likely that this function was
1869 // called in a wrong way (e.g. Root is before Prev).
1870 assert(SeenMI2 && "Prev is expected to appear before Root");
1871 }
1872
1873 // Tail / Mask policies
1874 if (RISCVII::hasVecPolicyOp(TSFlags) &&
1875 !checkImmOperand(RISCVII::getVecPolicyOpNum(Desc)))
1876 return false;
1877
1878 // VL
1879 if (RISCVII::hasVLOp(TSFlags)) {
1880 unsigned OpIdx = RISCVII::getVLOpNum(Desc);
1881 const MachineOperand &Op1 = Root.getOperand(OpIdx);
1882 const MachineOperand &Op2 = Prev.getOperand(OpIdx);
1883 if (Op1.getType() != Op2.getType())
1884 return false;
1885 switch (Op1.getType()) {
1887 if (Op1.getReg() != Op2.getReg())
1888 return false;
1889 break;
1891 if (Op1.getImm() != Op2.getImm())
1892 return false;
1893 break;
1894 default:
1895 llvm_unreachable("Unrecognized VL operand type");
1896 }
1897 }
1898
1899 // Rounding modes
1900 if (RISCVII::hasRoundModeOp(TSFlags) &&
1901 !checkImmOperand(RISCVII::getVLOpNum(Desc) - 1))
1902 return false;
1903
1904 return true;
1905}
1906
1907// Most of our RVV pseudos have passthru operand, so the real operands
1908// start from index = 2.
1909bool RISCVInstrInfo::hasReassociableVectorSibling(const MachineInstr &Inst,
1910 bool &Commuted) const {
1911 const MachineBasicBlock *MBB = Inst.getParent();
1914 "Expect the present of passthrough operand.");
1915 MachineInstr *MI1 = MRI.getUniqueVRegDef(Inst.getOperand(2).getReg());
1916 MachineInstr *MI2 = MRI.getUniqueVRegDef(Inst.getOperand(3).getReg());
1917
1918 // If only one operand has the same or inverse opcode and it's the second
1919 // source operand, the operands must be commuted.
1920 Commuted = !areRVVInstsReassociable(Inst, *MI1) &&
1921 areRVVInstsReassociable(Inst, *MI2);
1922 if (Commuted)
1923 std::swap(MI1, MI2);
1924
1925 return areRVVInstsReassociable(Inst, *MI1) &&
1926 (isVectorAssociativeAndCommutative(*MI1) ||
1927 isVectorAssociativeAndCommutative(*MI1, /* Invert */ true)) &&
1929 MRI.hasOneNonDBGUse(MI1->getOperand(0).getReg());
1930}
1931
1933 const MachineInstr &Inst, const MachineBasicBlock *MBB) const {
1934 if (!isVectorAssociativeAndCommutative(Inst) &&
1935 !isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
1937
1938 const MachineOperand &Op1 = Inst.getOperand(2);
1939 const MachineOperand &Op2 = Inst.getOperand(3);
1941
1942 // We need virtual register definitions for the operands that we will
1943 // reassociate.
1944 MachineInstr *MI1 = nullptr;
1945 MachineInstr *MI2 = nullptr;
1946 if (Op1.isReg() && Op1.getReg().isVirtual())
1947 MI1 = MRI.getUniqueVRegDef(Op1.getReg());
1948 if (Op2.isReg() && Op2.getReg().isVirtual())
1949 MI2 = MRI.getUniqueVRegDef(Op2.getReg());
1950
1951 // And at least one operand must be defined in MBB.
1952 return MI1 && MI2 && (MI1->getParent() == MBB || MI2->getParent() == MBB);
1953}
1954
1956 const MachineInstr &Root, unsigned Pattern,
1957 std::array<unsigned, 5> &OperandIndices) const {
1959 if (RISCV::getRVVMCOpcode(Root.getOpcode())) {
1960 // Skip the passthrough operand, so increment all indices by one.
1961 for (unsigned I = 0; I < 5; ++I)
1962 ++OperandIndices[I];
1963 }
1964}
1965
1967 bool &Commuted) const {
1968 if (isVectorAssociativeAndCommutative(Inst) ||
1969 isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
1970 return hasReassociableVectorSibling(Inst, Commuted);
1971
1972 if (!TargetInstrInfo::hasReassociableSibling(Inst, Commuted))
1973 return false;
1974
1975 const MachineRegisterInfo &MRI = Inst.getMF()->getRegInfo();
1976 unsigned OperandIdx = Commuted ? 2 : 1;
1977 const MachineInstr &Sibling =
1978 *MRI.getVRegDef(Inst.getOperand(OperandIdx).getReg());
1979
1980 int16_t InstFrmOpIdx =
1981 RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::frm);
1982 int16_t SiblingFrmOpIdx =
1983 RISCV::getNamedOperandIdx(Sibling.getOpcode(), RISCV::OpName::frm);
1984
1985 return (InstFrmOpIdx < 0 && SiblingFrmOpIdx < 0) ||
1986 RISCV::hasEqualFRM(Inst, Sibling);
1987}
1988
1990 bool Invert) const {
1991 if (isVectorAssociativeAndCommutative(Inst, Invert))
1992 return true;
1993
1994 unsigned Opc = Inst.getOpcode();
1995 if (Invert) {
1996 auto InverseOpcode = getInverseOpcode(Opc);
1997 if (!InverseOpcode)
1998 return false;
1999 Opc = *InverseOpcode;
2000 }
2001
2002 if (isFADD(Opc) || isFMUL(Opc))
2005
2006 switch (Opc) {
2007 default:
2008 return false;
2009 case RISCV::ADD:
2010 case RISCV::ADDW:
2011 case RISCV::AND:
2012 case RISCV::OR:
2013 case RISCV::XOR:
2014 // From RISC-V ISA spec, if both the high and low bits of the same product
2015 // are required, then the recommended code sequence is:
2016 //
2017 // MULH[[S]U] rdh, rs1, rs2
2018 // MUL rdl, rs1, rs2
2019 // (source register specifiers must be in same order and rdh cannot be the
2020 // same as rs1 or rs2)
2021 //
2022 // Microarchitectures can then fuse these into a single multiply operation
2023 // instead of performing two separate multiplies.
2024 // MachineCombiner may reassociate MUL operands and lose the fusion
2025 // opportunity.
2026 case RISCV::MUL:
2027 case RISCV::MULW:
2028 case RISCV::MIN:
2029 case RISCV::MINU:
2030 case RISCV::MAX:
2031 case RISCV::MAXU:
2032 case RISCV::FMIN_H:
2033 case RISCV::FMIN_S:
2034 case RISCV::FMIN_D:
2035 case RISCV::FMAX_H:
2036 case RISCV::FMAX_S:
2037 case RISCV::FMAX_D:
2038 return true;
2039 }
2040
2041 return false;
2042}
2043
2044std::optional<unsigned>
2045RISCVInstrInfo::getInverseOpcode(unsigned Opcode) const {
2046#define RVV_OPC_LMUL_CASE(OPC, INV) \
2047 case RISCV::OPC##_M1: \
2048 return RISCV::INV##_M1; \
2049 case RISCV::OPC##_M2: \
2050 return RISCV::INV##_M2; \
2051 case RISCV::OPC##_M4: \
2052 return RISCV::INV##_M4; \
2053 case RISCV::OPC##_M8: \
2054 return RISCV::INV##_M8; \
2055 case RISCV::OPC##_MF2: \
2056 return RISCV::INV##_MF2; \
2057 case RISCV::OPC##_MF4: \
2058 return RISCV::INV##_MF4; \
2059 case RISCV::OPC##_MF8: \
2060 return RISCV::INV##_MF8
2061
2062#define RVV_OPC_LMUL_MASK_CASE(OPC, INV) \
2063 case RISCV::OPC##_M1_MASK: \
2064 return RISCV::INV##_M1_MASK; \
2065 case RISCV::OPC##_M2_MASK: \
2066 return RISCV::INV##_M2_MASK; \
2067 case RISCV::OPC##_M4_MASK: \
2068 return RISCV::INV##_M4_MASK; \
2069 case RISCV::OPC##_M8_MASK: \
2070 return RISCV::INV##_M8_MASK; \
2071 case RISCV::OPC##_MF2_MASK: \
2072 return RISCV::INV##_MF2_MASK; \
2073 case RISCV::OPC##_MF4_MASK: \
2074 return RISCV::INV##_MF4_MASK; \
2075 case RISCV::OPC##_MF8_MASK: \
2076 return RISCV::INV##_MF8_MASK
2077
2078 switch (Opcode) {
2079 default:
2080 return std::nullopt;
2081 case RISCV::FADD_H:
2082 return RISCV::FSUB_H;
2083 case RISCV::FADD_S:
2084 return RISCV::FSUB_S;
2085 case RISCV::FADD_D:
2086 return RISCV::FSUB_D;
2087 case RISCV::FSUB_H:
2088 return RISCV::FADD_H;
2089 case RISCV::FSUB_S:
2090 return RISCV::FADD_S;
2091 case RISCV::FSUB_D:
2092 return RISCV::FADD_D;
2093 case RISCV::ADD:
2094 return RISCV::SUB;
2095 case RISCV::SUB:
2096 return RISCV::ADD;
2097 case RISCV::ADDW:
2098 return RISCV::SUBW;
2099 case RISCV::SUBW:
2100 return RISCV::ADDW;
2101 // clang-format off
2102 RVV_OPC_LMUL_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2103 RVV_OPC_LMUL_MASK_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2104 RVV_OPC_LMUL_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2105 RVV_OPC_LMUL_MASK_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2106 // clang-format on
2107 }
2108
2109#undef RVV_OPC_LMUL_MASK_CASE
2110#undef RVV_OPC_LMUL_CASE
2111}
2112
2114 const MachineOperand &MO,
2115 bool DoRegPressureReduce) {
2116 if (!MO.isReg() || !MO.getReg().isVirtual())
2117 return false;
2118 const MachineRegisterInfo &MRI = Root.getMF()->getRegInfo();
2119 MachineInstr *MI = MRI.getVRegDef(MO.getReg());
2120 if (!MI || !isFMUL(MI->getOpcode()))
2121 return false;
2122
2125 return false;
2126
2127 // Try combining even if fmul has more than one use as it eliminates
2128 // dependency between fadd(fsub) and fmul. However, it can extend liveranges
2129 // for fmul operands, so reject the transformation in register pressure
2130 // reduction mode.
2131 if (DoRegPressureReduce && !MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2132 return false;
2133
2134 // Do not combine instructions from different basic blocks.
2135 if (Root.getParent() != MI->getParent())
2136 return false;
2137 return RISCV::hasEqualFRM(Root, *MI);
2138}
2139
2141 SmallVectorImpl<unsigned> &Patterns,
2142 bool DoRegPressureReduce) {
2143 unsigned Opc = Root.getOpcode();
2144 bool IsFAdd = isFADD(Opc);
2145 if (!IsFAdd && !isFSUB(Opc))
2146 return false;
2147 bool Added = false;
2148 if (canCombineFPFusedMultiply(Root, Root.getOperand(1),
2149 DoRegPressureReduce)) {
2152 Added = true;
2153 }
2154 if (canCombineFPFusedMultiply(Root, Root.getOperand(2),
2155 DoRegPressureReduce)) {
2158 Added = true;
2159 }
2160 return Added;
2161}
2162
2163static bool getFPPatterns(MachineInstr &Root,
2164 SmallVectorImpl<unsigned> &Patterns,
2165 bool DoRegPressureReduce) {
2166 return getFPFusedMultiplyPatterns(Root, Patterns, DoRegPressureReduce);
2167}
2168
2169/// Utility routine that checks if \param MO is defined by an
2170/// \param CombineOpc instruction in the basic block \param MBB
2172 const MachineOperand &MO,
2173 unsigned CombineOpc) {
2175 const MachineInstr *MI = nullptr;
2176
2177 if (MO.isReg() && MO.getReg().isVirtual())
2178 MI = MRI.getUniqueVRegDef(MO.getReg());
2179 // And it needs to be in the trace (otherwise, it won't have a depth).
2180 if (!MI || MI->getParent() != &MBB || MI->getOpcode() != CombineOpc)
2181 return nullptr;
2182 // Must only used by the user we combine with.
2183 if (!MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2184 return nullptr;
2185
2186 return MI;
2187}
2188
2189/// Utility routine that checks if \param MO is defined by a SLLI in \param
2190/// MBB that can be combined by splitting across 2 SHXADD instructions. The
2191/// first SHXADD shift amount is given by \param OuterShiftAmt.
2193 const MachineOperand &MO,
2194 unsigned OuterShiftAmt) {
2195 const MachineInstr *ShiftMI = canCombine(MBB, MO, RISCV::SLLI);
2196 if (!ShiftMI)
2197 return false;
2198
2199 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2200 if (InnerShiftAmt < OuterShiftAmt || (InnerShiftAmt - OuterShiftAmt) > 3)
2201 return false;
2202
2203 return true;
2204}
2205
2206// Returns the shift amount from a SHXADD instruction. Returns 0 if the
2207// instruction is not a SHXADD.
2208static unsigned getSHXADDShiftAmount(unsigned Opc) {
2209 switch (Opc) {
2210 default:
2211 return 0;
2212 case RISCV::SH1ADD:
2213 return 1;
2214 case RISCV::SH2ADD:
2215 return 2;
2216 case RISCV::SH3ADD:
2217 return 3;
2218 }
2219}
2220
2221// Look for opportunities to combine (sh3add Z, (add X, (slli Y, 5))) into
2222// (sh3add (sh2add Y, Z), X).
2223static bool getSHXADDPatterns(const MachineInstr &Root,
2224 SmallVectorImpl<unsigned> &Patterns) {
2225 unsigned ShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2226 if (!ShiftAmt)
2227 return false;
2228
2229 const MachineBasicBlock &MBB = *Root.getParent();
2230
2231 const MachineInstr *AddMI = canCombine(MBB, Root.getOperand(2), RISCV::ADD);
2232 if (!AddMI)
2233 return false;
2234
2235 bool Found = false;
2236 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(1), ShiftAmt)) {
2238 Found = true;
2239 }
2240 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(2), ShiftAmt)) {
2242 Found = true;
2243 }
2244
2245 return Found;
2246}
2247
2249 switch (Pattern) {
2255 default:
2257 }
2258}
2259
2261 MachineInstr &Root, SmallVectorImpl<unsigned> &Patterns,
2262 bool DoRegPressureReduce) const {
2263
2264 if (getFPPatterns(Root, Patterns, DoRegPressureReduce))
2265 return true;
2266
2267 if (getSHXADDPatterns(Root, Patterns))
2268 return true;
2269
2270 return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
2271 DoRegPressureReduce);
2272}
2273
2274static unsigned getFPFusedMultiplyOpcode(unsigned RootOpc, unsigned Pattern) {
2275 switch (RootOpc) {
2276 default:
2277 llvm_unreachable("Unexpected opcode");
2278 case RISCV::FADD_H:
2279 return RISCV::FMADD_H;
2280 case RISCV::FADD_S:
2281 return RISCV::FMADD_S;
2282 case RISCV::FADD_D:
2283 return RISCV::FMADD_D;
2284 case RISCV::FSUB_H:
2285 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_H
2286 : RISCV::FNMSUB_H;
2287 case RISCV::FSUB_S:
2288 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_S
2289 : RISCV::FNMSUB_S;
2290 case RISCV::FSUB_D:
2291 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_D
2292 : RISCV::FNMSUB_D;
2293 }
2294}
2295
2296static unsigned getAddendOperandIdx(unsigned Pattern) {
2297 switch (Pattern) {
2298 default:
2299 llvm_unreachable("Unexpected pattern");
2302 return 2;
2305 return 1;
2306 }
2307}
2308
2310 unsigned Pattern,
2313 MachineFunction *MF = Root.getMF();
2316
2317 MachineOperand &Mul1 = Prev.getOperand(1);
2318 MachineOperand &Mul2 = Prev.getOperand(2);
2319 MachineOperand &Dst = Root.getOperand(0);
2321
2322 Register DstReg = Dst.getReg();
2323 unsigned FusedOpc = getFPFusedMultiplyOpcode(Root.getOpcode(), Pattern);
2324 uint32_t IntersectedFlags = Root.getFlags() & Prev.getFlags();
2325 DebugLoc MergedLoc =
2327
2328 bool Mul1IsKill = Mul1.isKill();
2329 bool Mul2IsKill = Mul2.isKill();
2330 bool AddendIsKill = Addend.isKill();
2331
2332 // We need to clear kill flags since we may be extending the live range past
2333 // a kill. If the mul had kill flags, we can preserve those since we know
2334 // where the previous range stopped.
2335 MRI.clearKillFlags(Mul1.getReg());
2336 MRI.clearKillFlags(Mul2.getReg());
2337
2339 BuildMI(*MF, MergedLoc, TII->get(FusedOpc), DstReg)
2340 .addReg(Mul1.getReg(), getKillRegState(Mul1IsKill))
2341 .addReg(Mul2.getReg(), getKillRegState(Mul2IsKill))
2342 .addReg(Addend.getReg(), getKillRegState(AddendIsKill))
2343 .setMIFlags(IntersectedFlags);
2344
2345 InsInstrs.push_back(MIB);
2346 if (MRI.hasOneNonDBGUse(Prev.getOperand(0).getReg()))
2347 DelInstrs.push_back(&Prev);
2348 DelInstrs.push_back(&Root);
2349}
2350
2351// Combine patterns like (sh3add Z, (add X, (slli Y, 5))) to
2352// (sh3add (sh2add Y, Z), X) if the shift amount can be split across two
2353// shXadd instructions. The outer shXadd keeps its original opcode.
2354static void
2355genShXAddAddShift(MachineInstr &Root, unsigned AddOpIdx,
2358 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) {
2359 MachineFunction *MF = Root.getMF();
2362
2363 unsigned OuterShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2364 assert(OuterShiftAmt != 0 && "Unexpected opcode");
2365
2366 MachineInstr *AddMI = MRI.getUniqueVRegDef(Root.getOperand(2).getReg());
2367 MachineInstr *ShiftMI =
2368 MRI.getUniqueVRegDef(AddMI->getOperand(AddOpIdx).getReg());
2369
2370 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2371 assert(InnerShiftAmt >= OuterShiftAmt && "Unexpected shift amount");
2372
2373 unsigned InnerOpc;
2374 switch (InnerShiftAmt - OuterShiftAmt) {
2375 default:
2376 llvm_unreachable("Unexpected shift amount");
2377 case 0:
2378 InnerOpc = RISCV::ADD;
2379 break;
2380 case 1:
2381 InnerOpc = RISCV::SH1ADD;
2382 break;
2383 case 2:
2384 InnerOpc = RISCV::SH2ADD;
2385 break;
2386 case 3:
2387 InnerOpc = RISCV::SH3ADD;
2388 break;
2389 }
2390
2391 const MachineOperand &X = AddMI->getOperand(3 - AddOpIdx);
2392 const MachineOperand &Y = ShiftMI->getOperand(1);
2393 const MachineOperand &Z = Root.getOperand(1);
2394
2395 Register NewVR = MRI.createVirtualRegister(&RISCV::GPRRegClass);
2396
2397 auto MIB1 = BuildMI(*MF, MIMetadata(Root), TII->get(InnerOpc), NewVR)
2398 .addReg(Y.getReg(), getKillRegState(Y.isKill()))
2399 .addReg(Z.getReg(), getKillRegState(Z.isKill()));
2400 auto MIB2 = BuildMI(*MF, MIMetadata(Root), TII->get(Root.getOpcode()),
2401 Root.getOperand(0).getReg())
2402 .addReg(NewVR, RegState::Kill)
2403 .addReg(X.getReg(), getKillRegState(X.isKill()));
2404
2405 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));
2406 InsInstrs.push_back(MIB1);
2407 InsInstrs.push_back(MIB2);
2408 DelInstrs.push_back(ShiftMI);
2409 DelInstrs.push_back(AddMI);
2410 DelInstrs.push_back(&Root);
2411}
2412
2414 MachineInstr &Root, unsigned Pattern,
2417 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const {
2419 switch (Pattern) {
2420 default:
2422 DelInstrs, InstrIdxForVirtReg);
2423 return;
2426 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(1).getReg());
2427 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2428 return;
2429 }
2432 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(2).getReg());
2433 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2434 return;
2435 }
2437 genShXAddAddShift(Root, 1, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2438 return;
2440 genShXAddAddShift(Root, 2, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2441 return;
2442 }
2443}
2444
2446 StringRef &ErrInfo) const {
2447 MCInstrDesc const &Desc = MI.getDesc();
2448
2449 for (const auto &[Index, Operand] : enumerate(Desc.operands())) {
2450 unsigned OpType = Operand.OperandType;
2451 if (OpType >= RISCVOp::OPERAND_FIRST_RISCV_IMM &&
2453 const MachineOperand &MO = MI.getOperand(Index);
2454 if (MO.isReg()) {
2455 ErrInfo = "Expected a non-register operand.";
2456 return false;
2457 }
2458 if (MO.isImm()) {
2459 int64_t Imm = MO.getImm();
2460 bool Ok;
2461 switch (OpType) {
2462 default:
2463 llvm_unreachable("Unexpected operand type");
2464
2465 // clang-format off
2466#define CASE_OPERAND_UIMM(NUM) \
2467 case RISCVOp::OPERAND_UIMM##NUM: \
2468 Ok = isUInt<NUM>(Imm); \
2469 break;
2480 // clang-format on
2482 Ok = isShiftedUInt<1, 1>(Imm);
2483 break;
2485 Ok = isShiftedUInt<4, 1>(Imm);
2486 break;
2488 Ok = isShiftedUInt<5, 1>(Imm);
2489 break;
2491 Ok = isShiftedUInt<5, 2>(Imm);
2492 break;
2494 Ok = isShiftedUInt<6, 2>(Imm);
2495 break;
2497 Ok = isShiftedUInt<5, 3>(Imm);
2498 break;
2500 Ok = isUInt<8>(Imm) && Imm >= 32;
2501 break;
2503 Ok = isShiftedUInt<6, 3>(Imm);
2504 break;
2506 Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
2507 break;
2509 Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0);
2510 break;
2512 Ok = Imm == 0;
2513 break;
2515 Ok = isInt<5>(Imm);
2516 break;
2518 Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16;
2519 break;
2521 Ok = isInt<6>(Imm);
2522 break;
2524 Ok = Imm != 0 && isInt<6>(Imm);
2525 break;
2527 Ok = isUInt<10>(Imm);
2528 break;
2530 Ok = isUInt<11>(Imm);
2531 break;
2533 Ok = isInt<12>(Imm);
2534 break;
2536 Ok = isShiftedInt<7, 5>(Imm);
2537 break;
2539 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
2540 break;
2542 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
2543 Ok = Ok && Imm != 0;
2544 break;
2546 Ok = (isUInt<5>(Imm) && Imm != 0) ||
2547 (Imm >= 0xfffe0 && Imm <= 0xfffff);
2548 break;
2550 Ok = Imm >= 0 && Imm <= 10;
2551 break;
2553 Ok = Imm >= 0 && Imm <= 7;
2554 break;
2556 Ok = Imm >= 1 && Imm <= 10;
2557 break;
2559 Ok = Imm >= 2 && Imm <= 14;
2560 break;
2562 Ok = (Imm & 0xf) == 0;
2563 break;
2566 break;
2568 Ok = Imm == RISCVFPRndMode::RTZ;
2569 break;
2571 Ok = Imm >= 0 && Imm < RISCVCC::COND_INVALID;
2572 break;
2574 Ok = (Imm & (RISCVII::TAIL_AGNOSTIC | RISCVII::MASK_AGNOSTIC)) == Imm;
2575 break;
2577 Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm));
2578 break;
2580 Ok = Imm == 0;
2581 break;
2584 if (RISCVII::usesVXRM(Desc.TSFlags))
2585 Ok = isUInt<2>(Imm);
2586 else
2588 break;
2589 }
2590 if (!Ok) {
2591 ErrInfo = "Invalid immediate";
2592 return false;
2593 }
2594 }
2595 }
2596 }
2597
2598 const uint64_t TSFlags = Desc.TSFlags;
2599 if (RISCVII::hasVLOp(TSFlags)) {
2600 const MachineOperand &Op = MI.getOperand(RISCVII::getVLOpNum(Desc));
2601 if (!Op.isImm() && !Op.isReg()) {
2602 ErrInfo = "Invalid operand type for VL operand";
2603 return false;
2604 }
2605 if (Op.isReg() && Op.getReg() != RISCV::NoRegister) {
2606 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
2607 auto *RC = MRI.getRegClass(Op.getReg());
2608 if (!RISCV::GPRRegClass.hasSubClassEq(RC)) {
2609 ErrInfo = "Invalid register class for VL operand";
2610 return false;
2611 }
2612 }
2613 if (!RISCVII::hasSEWOp(TSFlags)) {
2614 ErrInfo = "VL operand w/o SEW operand?";
2615 return false;
2616 }
2617 }
2618 if (RISCVII::hasSEWOp(TSFlags)) {
2619 unsigned OpIdx = RISCVII::getSEWOpNum(Desc);
2620 if (!MI.getOperand(OpIdx).isImm()) {
2621 ErrInfo = "SEW value expected to be an immediate";
2622 return false;
2623 }
2624 uint64_t Log2SEW = MI.getOperand(OpIdx).getImm();
2625 if (Log2SEW > 31) {
2626 ErrInfo = "Unexpected SEW value";
2627 return false;
2628 }
2629 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
2630 if (!RISCVVType::isValidSEW(SEW)) {
2631 ErrInfo = "Unexpected SEW value";
2632 return false;
2633 }
2634 }
2635 if (RISCVII::hasVecPolicyOp(TSFlags)) {
2636 unsigned OpIdx = RISCVII::getVecPolicyOpNum(Desc);
2637 if (!MI.getOperand(OpIdx).isImm()) {
2638 ErrInfo = "Policy operand expected to be an immediate";
2639 return false;
2640 }
2641 uint64_t Policy = MI.getOperand(OpIdx).getImm();
2643 ErrInfo = "Invalid Policy Value";
2644 return false;
2645 }
2646 if (!RISCVII::hasVLOp(TSFlags)) {
2647 ErrInfo = "policy operand w/o VL operand?";
2648 return false;
2649 }
2650
2651 // VecPolicy operands can only exist on instructions with passthru/merge
2652 // arguments. Note that not all arguments with passthru have vec policy
2653 // operands- some instructions have implicit policies.
2654 unsigned UseOpIdx;
2655 if (!MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
2656 ErrInfo = "policy operand w/o tied operand?";
2657 return false;
2658 }
2659 }
2660
2661 if (int Idx = RISCVII::getFRMOpNum(Desc);
2662 Idx >= 0 && MI.getOperand(Idx).getImm() == RISCVFPRndMode::DYN &&
2663 !MI.readsRegister(RISCV::FRM, /*TRI=*/nullptr)) {
2664 ErrInfo = "dynamic rounding mode should read FRM";
2665 return false;
2666 }
2667
2668 return true;
2669}
2670
2672 const MachineInstr &AddrI,
2673 ExtAddrMode &AM) const {
2674 switch (MemI.getOpcode()) {
2675 default:
2676 return false;
2677 case RISCV::LB:
2678 case RISCV::LBU:
2679 case RISCV::LH:
2680 case RISCV::LH_INX:
2681 case RISCV::LHU:
2682 case RISCV::LW:
2683 case RISCV::LW_INX:
2684 case RISCV::LWU:
2685 case RISCV::LD:
2686 case RISCV::FLH:
2687 case RISCV::FLW:
2688 case RISCV::FLD:
2689 case RISCV::SB:
2690 case RISCV::SH:
2691 case RISCV::SH_INX:
2692 case RISCV::SW:
2693 case RISCV::SW_INX:
2694 case RISCV::SD:
2695 case RISCV::FSH:
2696 case RISCV::FSW:
2697 case RISCV::FSD:
2698 break;
2699 }
2700
2701 if (MemI.getOperand(0).getReg() == Reg)
2702 return false;
2703
2704 if (AddrI.getOpcode() != RISCV::ADDI || !AddrI.getOperand(1).isReg() ||
2705 !AddrI.getOperand(2).isImm())
2706 return false;
2707
2708 int64_t OldOffset = MemI.getOperand(2).getImm();
2709 int64_t Disp = AddrI.getOperand(2).getImm();
2710 int64_t NewOffset = OldOffset + Disp;
2711 if (!STI.is64Bit())
2712 NewOffset = SignExtend64<32>(NewOffset);
2713
2714 if (!isInt<12>(NewOffset))
2715 return false;
2716
2717 AM.BaseReg = AddrI.getOperand(1).getReg();
2718 AM.ScaledReg = 0;
2719 AM.Scale = 0;
2720 AM.Displacement = NewOffset;
2722 return true;
2723}
2724
2726 const ExtAddrMode &AM) const {
2727
2728 const DebugLoc &DL = MemI.getDebugLoc();
2729 MachineBasicBlock &MBB = *MemI.getParent();
2730
2731 assert(AM.ScaledReg == 0 && AM.Scale == 0 &&
2732 "Addressing mode not supported for folding");
2733
2734 return BuildMI(MBB, MemI, DL, get(MemI.getOpcode()))
2735 .addReg(MemI.getOperand(0).getReg(),
2736 MemI.mayLoad() ? RegState::Define : 0)
2737 .addReg(AM.BaseReg)
2738 .addImm(AM.Displacement)
2739 .setMemRefs(MemI.memoperands())
2740 .setMIFlags(MemI.getFlags());
2741}
2742
2745 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
2746 const TargetRegisterInfo *TRI) const {
2747 if (!LdSt.mayLoadOrStore())
2748 return false;
2749
2750 // Conservatively, only handle scalar loads/stores for now.
2751 switch (LdSt.getOpcode()) {
2752 case RISCV::LB:
2753 case RISCV::LBU:
2754 case RISCV::SB:
2755 case RISCV::LH:
2756 case RISCV::LH_INX:
2757 case RISCV::LHU:
2758 case RISCV::FLH:
2759 case RISCV::SH:
2760 case RISCV::SH_INX:
2761 case RISCV::FSH:
2762 case RISCV::LW:
2763 case RISCV::LW_INX:
2764 case RISCV::LWU:
2765 case RISCV::FLW:
2766 case RISCV::SW:
2767 case RISCV::SW_INX:
2768 case RISCV::FSW:
2769 case RISCV::LD:
2770 case RISCV::FLD:
2771 case RISCV::SD:
2772 case RISCV::FSD:
2773 break;
2774 default:
2775 return false;
2776 }
2777 const MachineOperand *BaseOp;
2778 OffsetIsScalable = false;
2779 if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
2780 return false;
2781 BaseOps.push_back(BaseOp);
2782 return true;
2783}
2784
2785// TODO: This was copied from SIInstrInfo. Could it be lifted to a common
2786// helper?
2789 const MachineInstr &MI2,
2791 // Only examine the first "base" operand of each instruction, on the
2792 // assumption that it represents the real base address of the memory access.
2793 // Other operands are typically offsets or indices from this base address.
2794 if (BaseOps1.front()->isIdenticalTo(*BaseOps2.front()))
2795 return true;
2796
2797 if (!MI1.hasOneMemOperand() || !MI2.hasOneMemOperand())
2798 return false;
2799
2800 auto MO1 = *MI1.memoperands_begin();
2801 auto MO2 = *MI2.memoperands_begin();
2802 if (MO1->getAddrSpace() != MO2->getAddrSpace())
2803 return false;
2804
2805 auto Base1 = MO1->getValue();
2806 auto Base2 = MO2->getValue();
2807 if (!Base1 || !Base2)
2808 return false;
2809 Base1 = getUnderlyingObject(Base1);
2810 Base2 = getUnderlyingObject(Base2);
2811
2812 if (isa<UndefValue>(Base1) || isa<UndefValue>(Base2))
2813 return false;
2814
2815 return Base1 == Base2;
2816}
2817
2819 ArrayRef<const MachineOperand *> BaseOps1, int64_t Offset1,
2820 bool OffsetIsScalable1, ArrayRef<const MachineOperand *> BaseOps2,
2821 int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize,
2822 unsigned NumBytes) const {
2823 // If the mem ops (to be clustered) do not have the same base ptr, then they
2824 // should not be clustered
2825 if (!BaseOps1.empty() && !BaseOps2.empty()) {
2826 const MachineInstr &FirstLdSt = *BaseOps1.front()->getParent();
2827 const MachineInstr &SecondLdSt = *BaseOps2.front()->getParent();
2828 if (!memOpsHaveSameBasePtr(FirstLdSt, BaseOps1, SecondLdSt, BaseOps2))
2829 return false;
2830 } else if (!BaseOps1.empty() || !BaseOps2.empty()) {
2831 // If only one base op is empty, they do not have the same base ptr
2832 return false;
2833 }
2834
2835 unsigned CacheLineSize =
2836 BaseOps1.front()->getParent()->getMF()->getSubtarget().getCacheLineSize();
2837 // Assume a cache line size of 64 bytes if no size is set in RISCVSubtarget.
2839 // Cluster if the memory operations are on the same or a neighbouring cache
2840 // line, but limit the maximum ClusterSize to avoid creating too much
2841 // additional register pressure.
2842 return ClusterSize <= 4 && std::abs(Offset1 - Offset2) < CacheLineSize;
2843}
2844
2845// Set BaseReg (the base register operand), Offset (the byte offset being
2846// accessed) and the access Width of the passed instruction that reads/writes
2847// memory. Returns false if the instruction does not read/write memory or the
2848// BaseReg/Offset/Width can't be determined. Is not guaranteed to always
2849// recognise base operands and offsets in all cases.
2850// TODO: Add an IsScalable bool ref argument (like the equivalent AArch64
2851// function) and set it as appropriate.
2853 const MachineInstr &LdSt, const MachineOperand *&BaseReg, int64_t &Offset,
2854 LocationSize &Width, const TargetRegisterInfo *TRI) const {
2855 if (!LdSt.mayLoadOrStore())
2856 return false;
2857
2858 // Here we assume the standard RISC-V ISA, which uses a base+offset
2859 // addressing mode. You'll need to relax these conditions to support custom
2860 // load/store instructions.
2861 if (LdSt.getNumExplicitOperands() != 3)
2862 return false;
2863 if ((!LdSt.getOperand(1).isReg() && !LdSt.getOperand(1).isFI()) ||
2864 !LdSt.getOperand(2).isImm())
2865 return false;
2866
2867 if (!LdSt.hasOneMemOperand())
2868 return false;
2869
2870 Width = (*LdSt.memoperands_begin())->getSize();
2871 BaseReg = &LdSt.getOperand(1);
2872 Offset = LdSt.getOperand(2).getImm();
2873 return true;
2874}
2875
2877 const MachineInstr &MIa, const MachineInstr &MIb) const {
2878 assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
2879 assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");
2880
2883 return false;
2884
2885 // Retrieve the base register, offset from the base register and width. Width
2886 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4). If
2887 // base registers are identical, and the offset of a lower memory access +
2888 // the width doesn't overlap the offset of a higher memory access,
2889 // then the memory accesses are different.
2891 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
2892 int64_t OffsetA = 0, OffsetB = 0;
2893 LocationSize WidthA = 0, WidthB = 0;
2894 if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) &&
2895 getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) {
2896 if (BaseOpA->isIdenticalTo(*BaseOpB)) {
2897 int LowOffset = std::min(OffsetA, OffsetB);
2898 int HighOffset = std::max(OffsetA, OffsetB);
2899 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2900 if (LowWidth.hasValue() &&
2901 LowOffset + (int)LowWidth.getValue() <= HighOffset)
2902 return true;
2903 }
2904 }
2905 return false;
2906}
2907
2908std::pair<unsigned, unsigned>
2910 const unsigned Mask = RISCVII::MO_DIRECT_FLAG_MASK;
2911 return std::make_pair(TF & Mask, TF & ~Mask);
2912}
2913
2916 using namespace RISCVII;
2917 static const std::pair<unsigned, const char *> TargetFlags[] = {
2918 {MO_CALL, "riscv-call"},
2919 {MO_LO, "riscv-lo"},
2920 {MO_HI, "riscv-hi"},
2921 {MO_PCREL_LO, "riscv-pcrel-lo"},
2922 {MO_PCREL_HI, "riscv-pcrel-hi"},
2923 {MO_GOT_HI, "riscv-got-hi"},
2924 {MO_TPREL_LO, "riscv-tprel-lo"},
2925 {MO_TPREL_HI, "riscv-tprel-hi"},
2926 {MO_TPREL_ADD, "riscv-tprel-add"},
2927 {MO_TLS_GOT_HI, "riscv-tls-got-hi"},
2928 {MO_TLS_GD_HI, "riscv-tls-gd-hi"},
2929 {MO_TLSDESC_HI, "riscv-tlsdesc-hi"},
2930 {MO_TLSDESC_LOAD_LO, "riscv-tlsdesc-load-lo"},
2931 {MO_TLSDESC_ADD_LO, "riscv-tlsdesc-add-lo"},
2932 {MO_TLSDESC_CALL, "riscv-tlsdesc-call"}};
2933 return ArrayRef(TargetFlags);
2934}
2936 MachineFunction &MF, bool OutlineFromLinkOnceODRs) const {
2937 const Function &F = MF.getFunction();
2938
2939 // Can F be deduplicated by the linker? If it can, don't outline from it.
2940 if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage())
2941 return false;
2942
2943 // Don't outline from functions with section markings; the program could
2944 // expect that all the code is in the named section.
2945 if (F.hasSection())
2946 return false;
2947
2948 // It's safe to outline from MF.
2949 return true;
2950}
2951
2953 unsigned &Flags) const {
2954 // More accurate safety checking is done in getOutliningCandidateInfo.
2956}
2957
2958// Enum values indicating how an outlined call should be constructed.
2963
2965 MachineFunction &MF) const {
2966 return MF.getFunction().hasMinSize();
2967}
2968
2970 const MachineFunction *MF = MBB.getParent();
2971 const Function &F = MF->getFunction();
2972 return F.getFnAttribute("fentry-call").getValueAsBool() ||
2973 F.hasFnAttribute("patchable-function-entry");
2974}
2975
2977 unsigned RegNo) {
2978 return MI.readsRegister(RegNo, TRI) ||
2979 MI.getDesc().hasImplicitUseOfPhysReg(RegNo);
2980}
2981
2983 const TargetRegisterInfo *TRI, unsigned RegNo) {
2984 return MI.modifiesRegister(RegNo, TRI) ||
2985 MI.getDesc().hasImplicitDefOfPhysReg(RegNo);
2986}
2987
2989 if (!MBB.back().isReturn())
2990 return true;
2992 return true;
2993
2994 // If the candidate reads the pre-set register
2995 // that can be used for expanding PseudoTAIL instruction,
2996 // then we cannot insert tail call.
2998 unsigned TailExpandUseRegNo =
3000 for (const MachineInstr &MI : MBB) {
3001 if (isMIReadsReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
3002 return true;
3003 if (isMIModifiesReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
3004 break;
3005 }
3006 return false;
3007}
3008
3009static std::optional<MachineOutlinerConstructionID>
3011 // If last instruction is return then we can rely on
3012 // the verification already performed in the getOutliningTypeImpl.
3013 if (C.back().isReturn()) {
3014 assert(!cannotInsertTailCall(*C.getMBB()) &&
3015 "The candidate who uses return instruction must be outlined "
3016 "using tail call");
3018 }
3019
3020 auto CandidateUsesX5 = [](outliner::Candidate &C) {
3021 const TargetRegisterInfo *TRI = C.getMF()->getSubtarget().getRegisterInfo();
3022 if (std::any_of(C.begin(), C.end(), [TRI](const MachineInstr &MI) {
3023 return isMIModifiesReg(MI, TRI, RISCV::X5);
3024 }))
3025 return true;
3026 return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *TRI);
3027 };
3028
3029 if (!CandidateUsesX5(C))
3031
3032 return std::nullopt;
3033}
3034
3035std::optional<std::unique_ptr<outliner::OutlinedFunction>>
3037 const MachineModuleInfo &MMI,
3038 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
3039 unsigned MinRepeats) const {
3040
3041 // Each RepeatedSequenceLoc is identical.
3042 outliner::Candidate &Candidate = RepeatedSequenceLocs[0];
3043 auto CandidateInfo = analyzeCandidate(Candidate);
3044 if (!CandidateInfo)
3045 RepeatedSequenceLocs.clear();
3046
3047 // If the sequence doesn't have enough candidates left, then we're done.
3048 if (RepeatedSequenceLocs.size() < MinRepeats)
3049 return std::nullopt;
3050
3051 unsigned InstrSizeCExt =
3052 Candidate.getMF()->getSubtarget<RISCVSubtarget>().hasStdExtCOrZca() ? 2
3053 : 4;
3054 unsigned CallOverhead = 0, FrameOverhead = 0;
3055
3056 MachineOutlinerConstructionID MOCI = CandidateInfo.value();
3057 switch (MOCI) {
3059 // call t0, function = 8 bytes.
3060 CallOverhead = 8;
3061 // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
3062 FrameOverhead = InstrSizeCExt;
3063 break;
3065 // tail call = auipc + jalr in the worst case without linker relaxation.
3066 CallOverhead = 4 + InstrSizeCExt;
3067 // Using tail call we move ret instruction from caller to callee.
3068 FrameOverhead = 0;
3069 break;
3070 }
3071
3072 for (auto &C : RepeatedSequenceLocs)
3073 C.setCallInfo(MOCI, CallOverhead);
3074
3075 unsigned SequenceSize = 0;
3076 for (auto &MI : Candidate)
3077 SequenceSize += getInstSizeInBytes(MI);
3078
3079 return std::make_unique<outliner::OutlinedFunction>(
3080 RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI);
3081}
3082
3086 unsigned Flags) const {
3087 MachineInstr &MI = *MBBI;
3088 MachineBasicBlock *MBB = MI.getParent();
3089 const TargetRegisterInfo *TRI =
3091 const auto &F = MI.getMF()->getFunction();
3092
3093 // We can manually strip out CFI instructions later.
3094 if (MI.isCFIInstruction())
3095 // If current function has exception handling code, we can't outline &
3096 // strip these CFI instructions since it may break .eh_frame section
3097 // needed in unwinding.
3098 return F.needsUnwindTableEntry() ? outliner::InstrType::Illegal
3100
3101 if (cannotInsertTailCall(*MBB) &&
3102 (MI.isReturn() || isMIModifiesReg(MI, TRI, RISCV::X5)))
3104
3105 // Make sure the operands don't reference something unsafe.
3106 for (const auto &MO : MI.operands()) {
3107
3108 // pcrel-hi and pcrel-lo can't put in separate sections, filter that out
3109 // if any possible.
3110 if (MO.getTargetFlags() == RISCVII::MO_PCREL_LO &&
3111 (MI.getMF()->getTarget().getFunctionSections() || F.hasComdat() ||
3112 F.hasSection() || F.getSectionPrefix()))
3114 }
3115
3117}
3118
3121 const outliner::OutlinedFunction &OF) const {
3122
3123 // Strip out any CFI instructions
3124 bool Changed = true;
3125 while (Changed) {
3126 Changed = false;
3127 auto I = MBB.begin();
3128 auto E = MBB.end();
3129 for (; I != E; ++I) {
3130 if (I->isCFIInstruction()) {
3131 I->removeFromParent();
3132 Changed = true;
3133 break;
3134 }
3135 }
3136 }
3137
3139 return;
3140
3141 MBB.addLiveIn(RISCV::X5);
3142
3143 // Add in a return instruction to the end of the outlined frame.
3144 MBB.insert(MBB.end(), BuildMI(MF, DebugLoc(), get(RISCV::JALR))
3145 .addReg(RISCV::X0, RegState::Define)
3146 .addReg(RISCV::X5)
3147 .addImm(0));
3148}
3149
3153
3154 if (C.CallConstructionID == MachineOutlinerTailCall) {
3155 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoTAIL))
3156 .addGlobalAddress(M.getNamedValue(MF.getName()),
3157 /*Offset=*/0, RISCVII::MO_CALL));
3158 return It;
3159 }
3160
3161 // Add in a call instruction to the outlined function at the given location.
3162 It = MBB.insert(It,
3163 BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5)
3164 .addGlobalAddress(M.getNamedValue(MF.getName()), 0,
3166 return It;
3167}
3168
3169std::optional<RegImmPair> RISCVInstrInfo::isAddImmediate(const MachineInstr &MI,
3170 Register Reg) const {
3171 // TODO: Handle cases where Reg is a super- or sub-register of the
3172 // destination register.
3173 const MachineOperand &Op0 = MI.getOperand(0);
3174 if (!Op0.isReg() || Reg != Op0.getReg())
3175 return std::nullopt;
3176
3177 // Don't consider ADDIW as a candidate because the caller may not be aware
3178 // of its sign extension behaviour.
3179 if (MI.getOpcode() == RISCV::ADDI && MI.getOperand(1).isReg() &&
3180 MI.getOperand(2).isImm())
3181 return RegImmPair{MI.getOperand(1).getReg(), MI.getOperand(2).getImm()};
3182
3183 return std::nullopt;
3184}
3185
3186// MIR printer helper function to annotate Operands with a comment.
3188 const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx,
3189 const TargetRegisterInfo *TRI) const {
3190 // Print a generic comment for this operand if there is one.
3191 std::string GenericComment =
3193 if (!GenericComment.empty())
3194 return GenericComment;
3195
3196 // If not, we must have an immediate operand.
3197 if (!Op.isImm())
3198 return std::string();
3199
3200 const MCInstrDesc &Desc = MI.getDesc();
3201 if (OpIdx >= Desc.getNumOperands())
3202 return std::string();
3203
3204 std::string Comment;
3205 raw_string_ostream OS(Comment);
3206
3207 const MCOperandInfo &OpInfo = Desc.operands()[OpIdx];
3208
3209 // Print the full VType operand of vsetvli/vsetivli instructions, and the SEW
3210 // operand of vector codegen pseudos.
3211 switch (OpInfo.OperandType) {
3214 unsigned Imm = Op.getImm();
3216 break;
3217 }
3220 unsigned Log2SEW = Op.getImm();
3221 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3222 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
3223 OS << "e" << SEW;
3224 break;
3225 }
3227 unsigned Policy = Op.getImm();
3229 "Invalid Policy Value");
3230 OS << (Policy & RISCVII::TAIL_AGNOSTIC ? "ta" : "tu") << ", "
3231 << (Policy & RISCVII::MASK_AGNOSTIC ? "ma" : "mu");
3232 break;
3233 }
3234
3235 return Comment;
3236}
3237
3238// clang-format off
3239#define CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL) \
3240 RISCV::Pseudo##OP##_##LMUL
3241
3242#define CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL) \
3243 RISCV::Pseudo##OP##_##LMUL##_MASK
3244
3245#define CASE_RVV_OPCODE_LMUL(OP, LMUL) \
3246 CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL): \
3247 case CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL)
3248
3249#define CASE_RVV_OPCODE_UNMASK_WIDEN(OP) \
3250 CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF8): \
3251 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF4): \
3252 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF2): \
3253 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M1): \
3254 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M2): \
3255 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M4)
3256
3257#define CASE_RVV_OPCODE_UNMASK(OP) \
3258 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
3259 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M8)
3260
3261#define CASE_RVV_OPCODE_MASK_WIDEN(OP) \
3262 CASE_RVV_OPCODE_MASK_LMUL(OP, MF8): \
3263 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF4): \
3264 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF2): \
3265 case CASE_RVV_OPCODE_MASK_LMUL(OP, M1): \
3266 case CASE_RVV_OPCODE_MASK_LMUL(OP, M2): \
3267 case CASE_RVV_OPCODE_MASK_LMUL(OP, M4)
3268
3269#define CASE_RVV_OPCODE_MASK(OP) \
3270 CASE_RVV_OPCODE_MASK_WIDEN(OP): \
3271 case CASE_RVV_OPCODE_MASK_LMUL(OP, M8)
3272
3273#define CASE_RVV_OPCODE_WIDEN(OP) \
3274 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
3275 case CASE_RVV_OPCODE_MASK_WIDEN(OP)
3276
3277#define CASE_RVV_OPCODE(OP) \
3278 CASE_RVV_OPCODE_UNMASK(OP): \
3279 case CASE_RVV_OPCODE_MASK(OP)
3280// clang-format on
3281
3282// clang-format off
3283#define CASE_VMA_OPCODE_COMMON(OP, TYPE, LMUL) \
3284 RISCV::PseudoV##OP##_##TYPE##_##LMUL
3285
3286#define CASE_VMA_OPCODE_LMULS_M1(OP, TYPE) \
3287 CASE_VMA_OPCODE_COMMON(OP, TYPE, M1): \
3288 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M2): \
3289 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M4): \
3290 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M8)
3291
3292#define CASE_VMA_OPCODE_LMULS_MF2(OP, TYPE) \
3293 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF2): \
3294 case CASE_VMA_OPCODE_LMULS_M1(OP, TYPE)
3295
3296#define CASE_VMA_OPCODE_LMULS_MF4(OP, TYPE) \
3297 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF4): \
3298 case CASE_VMA_OPCODE_LMULS_MF2(OP, TYPE)
3299
3300#define CASE_VMA_OPCODE_LMULS(OP, TYPE) \
3301 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF8): \
3302 case CASE_VMA_OPCODE_LMULS_MF4(OP, TYPE)
3303
3304// VFMA instructions are SEW specific.
3305#define CASE_VFMA_OPCODE_COMMON(OP, TYPE, LMUL, SEW) \
3306 RISCV::PseudoV##OP##_##TYPE##_##LMUL##_##SEW
3307
3308#define CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW) \
3309 CASE_VFMA_OPCODE_COMMON(OP, TYPE, M1, SEW): \
3310 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M2, SEW): \
3311 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M4, SEW): \
3312 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M8, SEW)
3313
3314#define CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW) \
3315 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF2, SEW): \
3316 case CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW)
3317
3318#define CASE_VFMA_OPCODE_LMULS_MF4(OP, TYPE, SEW) \
3319 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF4, SEW): \
3320 case CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW)
3321
3322#define CASE_VFMA_OPCODE_VV(OP) \
3323 CASE_VFMA_OPCODE_LMULS_MF4(OP, VV, E16): \
3324 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VV, E32): \
3325 case CASE_VFMA_OPCODE_LMULS_M1(OP, VV, E64)
3326
3327#define CASE_VFMA_SPLATS(OP) \
3328 CASE_VFMA_OPCODE_LMULS_MF4(OP, VFPR16, E16): \
3329 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VFPR32, E32): \
3330 case CASE_VFMA_OPCODE_LMULS_M1(OP, VFPR64, E64)
3331// clang-format on
3332
3334 unsigned &SrcOpIdx1,
3335 unsigned &SrcOpIdx2) const {
3336 const MCInstrDesc &Desc = MI.getDesc();
3337 if (!Desc.isCommutable())
3338 return false;
3339
3340 switch (MI.getOpcode()) {
3341 case RISCV::TH_MVEQZ:
3342 case RISCV::TH_MVNEZ:
3343 // We can't commute operands if operand 2 (i.e., rs1 in
3344 // mveqz/mvnez rd,rs1,rs2) is the zero-register (as it is
3345 // not valid as the in/out-operand 1).
3346 if (MI.getOperand(2).getReg() == RISCV::X0)
3347 return false;
3348 // Operands 1 and 2 are commutable, if we switch the opcode.
3349 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
3350 case RISCV::TH_MULA:
3351 case RISCV::TH_MULAW:
3352 case RISCV::TH_MULAH:
3353 case RISCV::TH_MULS:
3354 case RISCV::TH_MULSW:
3355 case RISCV::TH_MULSH:
3356 // Operands 2 and 3 are commutable.
3357 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
3358 case RISCV::PseudoCCMOVGPRNoX0:
3359 case RISCV::PseudoCCMOVGPR:
3360 // Operands 4 and 5 are commutable.
3361 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 4, 5);
3362 case CASE_RVV_OPCODE(VADD_VV):
3363 case CASE_RVV_OPCODE(VAND_VV):
3364 case CASE_RVV_OPCODE(VOR_VV):
3365 case CASE_RVV_OPCODE(VXOR_VV):
3366 case CASE_RVV_OPCODE_MASK(VMSEQ_VV):
3367 case CASE_RVV_OPCODE_MASK(VMSNE_VV):
3368 case CASE_RVV_OPCODE(VMIN_VV):
3369 case CASE_RVV_OPCODE(VMINU_VV):
3370 case CASE_RVV_OPCODE(VMAX_VV):
3371 case CASE_RVV_OPCODE(VMAXU_VV):
3372 case CASE_RVV_OPCODE(VMUL_VV):
3373 case CASE_RVV_OPCODE(VMULH_VV):
3374 case CASE_RVV_OPCODE(VMULHU_VV):
3375 case CASE_RVV_OPCODE_WIDEN(VWADD_VV):
3376 case CASE_RVV_OPCODE_WIDEN(VWADDU_VV):
3377 case CASE_RVV_OPCODE_WIDEN(VWMUL_VV):
3378 case CASE_RVV_OPCODE_WIDEN(VWMULU_VV):
3379 case CASE_RVV_OPCODE_WIDEN(VWMACC_VV):
3380 case CASE_RVV_OPCODE_WIDEN(VWMACCU_VV):
3381 case CASE_RVV_OPCODE_UNMASK(VADC_VVM):
3382 case CASE_RVV_OPCODE(VSADD_VV):
3383 case CASE_RVV_OPCODE(VSADDU_VV):
3384 case CASE_RVV_OPCODE(VAADD_VV):
3385 case CASE_RVV_OPCODE(VAADDU_VV):
3386 case CASE_RVV_OPCODE(VSMUL_VV):
3387 // Operands 2 and 3 are commutable.
3388 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
3389 case CASE_VFMA_SPLATS(FMADD):
3390 case CASE_VFMA_SPLATS(FMSUB):
3391 case CASE_VFMA_SPLATS(FMACC):
3392 case CASE_VFMA_SPLATS(FMSAC):
3395 case CASE_VFMA_SPLATS(FNMACC):
3396 case CASE_VFMA_SPLATS(FNMSAC):
3397 case CASE_VFMA_OPCODE_VV(FMACC):
3398 case CASE_VFMA_OPCODE_VV(FMSAC):
3399 case CASE_VFMA_OPCODE_VV(FNMACC):
3400 case CASE_VFMA_OPCODE_VV(FNMSAC):
3401 case CASE_VMA_OPCODE_LMULS(MADD, VX):
3402 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
3403 case CASE_VMA_OPCODE_LMULS(MACC, VX):
3404 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
3405 case CASE_VMA_OPCODE_LMULS(MACC, VV):
3406 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
3407 // If the tail policy is undisturbed we can't commute.
3408 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
3409 if ((MI.getOperand(MI.getNumExplicitOperands() - 1).getImm() & 1) == 0)
3410 return false;
3411
3412 // For these instructions we can only swap operand 1 and operand 3 by
3413 // changing the opcode.
3414 unsigned CommutableOpIdx1 = 1;
3415 unsigned CommutableOpIdx2 = 3;
3416 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
3417 CommutableOpIdx2))
3418 return false;
3419 return true;
3420 }
3421 case CASE_VFMA_OPCODE_VV(FMADD):
3425 case CASE_VMA_OPCODE_LMULS(MADD, VV):
3426 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
3427 // If the tail policy is undisturbed we can't commute.
3428 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
3429 if ((MI.getOperand(MI.getNumExplicitOperands() - 1).getImm() & 1) == 0)
3430 return false;
3431
3432 // For these instructions we have more freedom. We can commute with the
3433 // other multiplicand or with the addend/subtrahend/minuend.
3434
3435 // Any fixed operand must be from source 1, 2 or 3.
3436 if (SrcOpIdx1 != CommuteAnyOperandIndex && SrcOpIdx1 > 3)
3437 return false;
3438 if (SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx2 > 3)
3439 return false;
3440
3441 // It both ops are fixed one must be the tied source.
3442 if (SrcOpIdx1 != CommuteAnyOperandIndex &&
3443 SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx1 != 1 && SrcOpIdx2 != 1)
3444 return false;
3445
3446 // Look for two different register operands assumed to be commutable
3447 // regardless of the FMA opcode. The FMA opcode is adjusted later if
3448 // needed.
3449 if (SrcOpIdx1 == CommuteAnyOperandIndex ||
3450 SrcOpIdx2 == CommuteAnyOperandIndex) {
3451 // At least one of operands to be commuted is not specified and
3452 // this method is free to choose appropriate commutable operands.
3453 unsigned CommutableOpIdx1 = SrcOpIdx1;
3454 if (SrcOpIdx1 == SrcOpIdx2) {
3455 // Both of operands are not fixed. Set one of commutable
3456 // operands to the tied source.
3457 CommutableOpIdx1 = 1;
3458 } else if (SrcOpIdx1 == CommuteAnyOperandIndex) {
3459 // Only one of the operands is not fixed.
3460 CommutableOpIdx1 = SrcOpIdx2;
3461 }
3462
3463 // CommutableOpIdx1 is well defined now. Let's choose another commutable
3464 // operand and assign its index to CommutableOpIdx2.
3465 unsigned CommutableOpIdx2;
3466 if (CommutableOpIdx1 != 1) {
3467 // If we haven't already used the tied source, we must use it now.
3468 CommutableOpIdx2 = 1;
3469 } else {
3470 Register Op1Reg = MI.getOperand(CommutableOpIdx1).getReg();
3471
3472 // The commuted operands should have different registers.
3473 // Otherwise, the commute transformation does not change anything and
3474 // is useless. We use this as a hint to make our decision.
3475 if (Op1Reg != MI.getOperand(2).getReg())
3476 CommutableOpIdx2 = 2;
3477 else
3478 CommutableOpIdx2 = 3;
3479 }
3480
3481 // Assign the found pair of commutable indices to SrcOpIdx1 and
3482 // SrcOpIdx2 to return those values.
3483 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
3484 CommutableOpIdx2))
3485 return false;
3486 }
3487
3488 return true;
3489 }
3490 }
3491
3492 return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
3493}
3494
3495// clang-format off
3496#define CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL) \
3497 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL: \
3498 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL; \
3499 break;
3500
3501#define CASE_VMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE) \
3502 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1) \
3503 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2) \
3504 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4) \
3505 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8)
3506
3507#define CASE_VMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE) \
3508 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2) \
3509 CASE_VMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE)
3510
3511#define CASE_VMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE) \
3512 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4) \
3513 CASE_VMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE)
3514
3515#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE) \
3516 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8) \
3517 CASE_VMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE)
3518
3519#define CASE_VMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
3520 CASE_VMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16) \
3521 CASE_VMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32) \
3522 CASE_VMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64)
3523
3524// VFMA depends on SEW.
3525#define CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL, SEW) \
3526 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL##_##SEW: \
3527 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL##_##SEW; \
3528 break;
3529
3530#define CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW) \
3531 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1, SEW) \
3532 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2, SEW) \
3533 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4, SEW) \
3534 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8, SEW)
3535
3536#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW) \
3537 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2, SEW) \
3538 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW)
3539
3540#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP) \
3541 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VV, E16) \
3542 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VV, E32) \
3543 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VV, E64)
3544
3545#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW) \
3546 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4, SEW) \
3547 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW)
3548
3549#define CASE_VFMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE, SEW) \
3550 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8, SEW) \
3551 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW)
3552
3553#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
3554 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
3555 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
3556 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
3557
3559 bool NewMI,
3560 unsigned OpIdx1,
3561 unsigned OpIdx2) const {
3562 auto cloneIfNew = [NewMI](MachineInstr &MI) -> MachineInstr & {
3563 if (NewMI)
3564 return *MI.getParent()->getParent()->CloneMachineInstr(&MI);
3565 return MI;
3566 };
3567
3568 switch (MI.getOpcode()) {
3569 case RISCV::TH_MVEQZ:
3570 case RISCV::TH_MVNEZ: {
3571 auto &WorkingMI = cloneIfNew(MI);
3572 WorkingMI.setDesc(get(MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
3573 : RISCV::TH_MVEQZ));
3574 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, false, OpIdx1,
3575 OpIdx2);
3576 }
3577 case RISCV::PseudoCCMOVGPRNoX0:
3578 case RISCV::PseudoCCMOVGPR: {
3579 // CCMOV can be commuted by inverting the condition.
3580 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
3582 auto &WorkingMI = cloneIfNew(MI);
3583 WorkingMI.getOperand(3).setImm(CC);
3584 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI*/ false,
3585 OpIdx1, OpIdx2);
3586 }
3587 case CASE_VFMA_SPLATS(FMACC):
3588 case CASE_VFMA_SPLATS(FMADD):
3589 case CASE_VFMA_SPLATS(FMSAC):
3590 case CASE_VFMA_SPLATS(FMSUB):
3591 case CASE_VFMA_SPLATS(FNMACC):
3593 case CASE_VFMA_SPLATS(FNMSAC):
3595 case CASE_VFMA_OPCODE_VV(FMACC):
3596 case CASE_VFMA_OPCODE_VV(FMSAC):
3597 case CASE_VFMA_OPCODE_VV(FNMACC):
3598 case CASE_VFMA_OPCODE_VV(FNMSAC):
3599 case CASE_VMA_OPCODE_LMULS(MADD, VX):
3600 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
3601 case CASE_VMA_OPCODE_LMULS(MACC, VX):
3602 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
3603 case CASE_VMA_OPCODE_LMULS(MACC, VV):
3604 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
3605 // It only make sense to toggle these between clobbering the
3606 // addend/subtrahend/minuend one of the multiplicands.
3607 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
3608 assert((OpIdx1 == 3 || OpIdx2 == 3) && "Unexpected opcode index");
3609 unsigned Opc;
3610 switch (MI.getOpcode()) {
3611 default:
3612 llvm_unreachable("Unexpected opcode");
3613 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMACC, FMADD)
3614 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMADD, FMACC)
3621 CASE_VFMA_CHANGE_OPCODE_VV(FMACC, FMADD)
3625 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VX)
3626 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VX)
3627 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VX)
3628 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VX)
3629 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VV)
3630 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VV)
3631 }
3632
3633 auto &WorkingMI = cloneIfNew(MI);
3634 WorkingMI.setDesc(get(Opc));
3635 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
3636 OpIdx1, OpIdx2);
3637 }
3638 case CASE_VFMA_OPCODE_VV(FMADD):
3642 case CASE_VMA_OPCODE_LMULS(MADD, VV):
3643 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
3644 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
3645 // If one of the operands, is the addend we need to change opcode.
3646 // Otherwise we're just swapping 2 of the multiplicands.
3647 if (OpIdx1 == 3 || OpIdx2 == 3) {
3648 unsigned Opc;
3649 switch (MI.getOpcode()) {
3650 default:
3651 llvm_unreachable("Unexpected opcode");
3652 CASE_VFMA_CHANGE_OPCODE_VV(FMADD, FMACC)
3656 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VV)
3657 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VV)
3658 }
3659
3660 auto &WorkingMI = cloneIfNew(MI);
3661 WorkingMI.setDesc(get(Opc));
3662 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
3663 OpIdx1, OpIdx2);
3664 }
3665 // Let the default code handle it.
3666 break;
3667 }
3668 }
3669
3670 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
3671}
3672
3673#undef CASE_RVV_OPCODE_UNMASK_LMUL
3674#undef CASE_RVV_OPCODE_MASK_LMUL
3675#undef CASE_RVV_OPCODE_LMUL
3676#undef CASE_RVV_OPCODE_UNMASK_WIDEN
3677#undef CASE_RVV_OPCODE_UNMASK
3678#undef CASE_RVV_OPCODE_MASK_WIDEN
3679#undef CASE_RVV_OPCODE_MASK
3680#undef CASE_RVV_OPCODE_WIDEN
3681#undef CASE_RVV_OPCODE
3682
3683#undef CASE_VMA_OPCODE_COMMON
3684#undef CASE_VMA_OPCODE_LMULS_M1
3685#undef CASE_VMA_OPCODE_LMULS_MF2
3686#undef CASE_VMA_OPCODE_LMULS_MF4
3687#undef CASE_VMA_OPCODE_LMULS
3688#undef CASE_VFMA_OPCODE_COMMON
3689#undef CASE_VFMA_OPCODE_LMULS_M1
3690#undef CASE_VFMA_OPCODE_LMULS_MF2
3691#undef CASE_VFMA_OPCODE_LMULS_MF4
3692#undef CASE_VFMA_OPCODE_VV
3693#undef CASE_VFMA_SPLATS
3694
3695// clang-format off
3696#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
3697 RISCV::PseudoV##OP##_##LMUL##_TIED
3698
3699#define CASE_WIDEOP_OPCODE_LMULS_MF4(OP) \
3700 CASE_WIDEOP_OPCODE_COMMON(OP, MF4): \
3701 case CASE_WIDEOP_OPCODE_COMMON(OP, MF2): \
3702 case CASE_WIDEOP_OPCODE_COMMON(OP, M1): \
3703 case CASE_WIDEOP_OPCODE_COMMON(OP, M2): \
3704 case CASE_WIDEOP_OPCODE_COMMON(OP, M4)
3705
3706#define CASE_WIDEOP_OPCODE_LMULS(OP) \
3707 CASE_WIDEOP_OPCODE_COMMON(OP, MF8): \
3708 case CASE_WIDEOP_OPCODE_LMULS_MF4(OP)
3709
3710#define CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL) \
3711 case RISCV::PseudoV##OP##_##LMUL##_TIED: \
3712 NewOpc = RISCV::PseudoV##OP##_##LMUL; \
3713 break;
3714
3715#define CASE_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP) \
3716 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4) \
3717 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2) \
3718 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1) \
3719 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2) \
3720 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4)
3721
3722#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
3723 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF8) \
3724 CASE_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP)
3725
3726// FP Widening Ops may by SEW aware. Create SEW aware cases for these cases.
3727#define CASE_FP_WIDEOP_OPCODE_COMMON(OP, LMUL, SEW) \
3728 RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED
3729
3730#define CASE_FP_WIDEOP_OPCODE_LMULS_MF4(OP) \
3731 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
3732 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
3733 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E32): \
3734 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
3735 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E32): \
3736 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
3737 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E32): \
3738 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16): \
3739 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E32) \
3740
3741#define CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL, SEW) \
3742 case RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED: \
3743 NewOpc = RISCV::PseudoV##OP##_##LMUL##_##SEW; \
3744 break;
3745
3746#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP) \
3747 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
3748 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
3749 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E32) \
3750 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
3751 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E32) \
3752 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
3753 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E32) \
3754 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16) \
3755 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E32) \
3756
3757#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
3758 CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP)
3759// clang-format on
3760
3762 LiveVariables *LV,
3763 LiveIntervals *LIS) const {
3765 switch (MI.getOpcode()) {
3766 default:
3767 return nullptr;
3768 case CASE_FP_WIDEOP_OPCODE_LMULS_MF4(FWADD_WV):
3769 case CASE_FP_WIDEOP_OPCODE_LMULS_MF4(FWSUB_WV): {
3770 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
3771 MI.getNumExplicitOperands() == 7 &&
3772 "Expect 7 explicit operands rd, rs2, rs1, rm, vl, sew, policy");
3773 // If the tail policy is undisturbed we can't convert.
3774 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
3775 1) == 0)
3776 return nullptr;
3777 // clang-format off
3778 unsigned NewOpc;
3779 switch (MI.getOpcode()) {
3780 default:
3781 llvm_unreachable("Unexpected opcode");
3784 }
3785 // clang-format on
3786
3787 MachineBasicBlock &MBB = *MI.getParent();
3788 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
3789 .add(MI.getOperand(0))
3790 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
3791 .add(MI.getOperand(1))
3792 .add(MI.getOperand(2))
3793 .add(MI.getOperand(3))
3794 .add(MI.getOperand(4))
3795 .add(MI.getOperand(5))
3796 .add(MI.getOperand(6));
3797 break;
3798 }
3799 case CASE_WIDEOP_OPCODE_LMULS(WADD_WV):
3800 case CASE_WIDEOP_OPCODE_LMULS(WADDU_WV):
3801 case CASE_WIDEOP_OPCODE_LMULS(WSUB_WV):
3802 case CASE_WIDEOP_OPCODE_LMULS(WSUBU_WV): {
3803 // If the tail policy is undisturbed we can't convert.
3804 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
3805 MI.getNumExplicitOperands() == 6);
3806 if ((MI.getOperand(5).getImm() & 1) == 0)
3807 return nullptr;
3808
3809 // clang-format off
3810 unsigned NewOpc;
3811 switch (MI.getOpcode()) {
3812 default:
3813 llvm_unreachable("Unexpected opcode");
3818 }
3819 // clang-format on
3820
3821 MachineBasicBlock &MBB = *MI.getParent();
3822 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
3823 .add(MI.getOperand(0))
3824 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
3825 .add(MI.getOperand(1))
3826 .add(MI.getOperand(2))
3827 .add(MI.getOperand(3))
3828 .add(MI.getOperand(4))
3829 .add(MI.getOperand(5));
3830 break;
3831 }
3832 }
3833 MIB.copyImplicitOps(MI);
3834
3835 if (LV) {
3836 unsigned NumOps = MI.getNumOperands();
3837 for (unsigned I = 1; I < NumOps; ++I) {
3838 MachineOperand &Op = MI.getOperand(I);
3839 if (Op.isReg() && Op.isKill())
3840 LV->replaceKillInstruction(Op.getReg(), MI, *MIB);
3841 }
3842 }
3843
3844 if (LIS) {
3846
3847 if (MI.getOperand(0).isEarlyClobber()) {
3848 // Use operand 1 was tied to early-clobber def operand 0, so its live
3849 // interval could have ended at an early-clobber slot. Now they are not
3850 // tied we need to update it to the normal register slot.
3851 LiveInterval &LI = LIS->getInterval(MI.getOperand(1).getReg());
3853 if (S->end == Idx.getRegSlot(true))
3854 S->end = Idx.getRegSlot();
3855 }
3856 }
3857
3858 return MIB;
3859}
3860
3861#undef CASE_WIDEOP_OPCODE_COMMON
3862#undef CASE_WIDEOP_OPCODE_LMULS_MF4
3863#undef CASE_WIDEOP_OPCODE_LMULS
3864#undef CASE_WIDEOP_CHANGE_OPCODE_COMMON
3865#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS_MF4
3866#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS
3867#undef CASE_FP_WIDEOP_OPCODE_COMMON
3868#undef CASE_FP_WIDEOP_OPCODE_LMULS_MF4
3869#undef CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON
3870#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4
3871#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS
3872
3875 Register DestReg, uint32_t Amount,
3876 MachineInstr::MIFlag Flag) const {
3878 if (llvm::has_single_bit<uint32_t>(Amount)) {
3879 uint32_t ShiftAmount = Log2_32(Amount);
3880 if (ShiftAmount == 0)
3881 return;
3882 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
3883 .addReg(DestReg, RegState::Kill)
3884 .addImm(ShiftAmount)
3885 .setMIFlag(Flag);
3886 } else if (STI.hasStdExtZba() &&
3887 ((Amount % 3 == 0 && isPowerOf2_64(Amount / 3)) ||
3888 (Amount % 5 == 0 && isPowerOf2_64(Amount / 5)) ||
3889 (Amount % 9 == 0 && isPowerOf2_64(Amount / 9)))) {
3890 // We can use Zba SHXADD+SLLI instructions for multiply in some cases.
3891 unsigned Opc;
3892 uint32_t ShiftAmount;
3893 if (Amount % 9 == 0) {
3894 Opc = RISCV::SH3ADD;
3895 ShiftAmount = Log2_64(Amount / 9);
3896 } else if (Amount % 5 == 0) {
3897 Opc = RISCV::SH2ADD;
3898 ShiftAmount = Log2_64(Amount / 5);
3899 } else if (Amount % 3 == 0) {
3900 Opc = RISCV::SH1ADD;
3901 ShiftAmount = Log2_64(Amount / 3);
3902 } else {
3903 llvm_unreachable("implied by if-clause");
3904 }
3905 if (ShiftAmount)
3906 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
3907 .addReg(DestReg, RegState::Kill)
3908 .addImm(ShiftAmount)
3909 .setMIFlag(Flag);
3910 BuildMI(MBB, II, DL, get(Opc), DestReg)
3911 .addReg(DestReg, RegState::Kill)
3912 .addReg(DestReg)
3913 .setMIFlag(Flag);
3914 } else if (llvm::has_single_bit<uint32_t>(Amount - 1)) {
3915 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
3916 uint32_t ShiftAmount = Log2_32(Amount - 1);
3917 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
3918 .addReg(DestReg)
3919 .addImm(ShiftAmount)
3920 .setMIFlag(Flag);
3921 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
3922 .addReg(ScaledRegister, RegState::Kill)
3923 .addReg(DestReg, RegState::Kill)
3924 .setMIFlag(Flag);
3925 } else if (llvm::has_single_bit<uint32_t>(Amount + 1)) {
3926 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
3927 uint32_t ShiftAmount = Log2_32(Amount + 1);
3928 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
3929 .addReg(DestReg)
3930 .addImm(ShiftAmount)
3931 .setMIFlag(Flag);
3932 BuildMI(MBB, II, DL, get(RISCV::SUB), DestReg)
3933 .addReg(ScaledRegister, RegState::Kill)
3934 .addReg(DestReg, RegState::Kill)
3935 .setMIFlag(Flag);
3936 } else if (STI.hasStdExtZmmul()) {
3937 Register N = MRI.createVirtualRegister(&RISCV::GPRRegClass);
3938 movImm(MBB, II, DL, N, Amount, Flag);
3939 BuildMI(MBB, II, DL, get(RISCV::MUL), DestReg)
3940 .addReg(DestReg, RegState::Kill)
3942 .setMIFlag(Flag);
3943 } else {
3944 Register Acc;
3945 uint32_t PrevShiftAmount = 0;
3946 for (uint32_t ShiftAmount = 0; Amount >> ShiftAmount; ShiftAmount++) {
3947 if (Amount & (1U << ShiftAmount)) {
3948 if (ShiftAmount)
3949 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
3950 .addReg(DestReg, RegState::Kill)
3951 .addImm(ShiftAmount - PrevShiftAmount)
3952 .setMIFlag(Flag);
3953 if (Amount >> (ShiftAmount + 1)) {
3954 // If we don't have an accmulator yet, create it and copy DestReg.
3955 if (!Acc) {
3956 Acc = MRI.createVirtualRegister(&RISCV::GPRRegClass);
3957 BuildMI(MBB, II, DL, get(TargetOpcode::COPY), Acc)
3958 .addReg(DestReg)
3959 .setMIFlag(Flag);
3960 } else {
3961 BuildMI(MBB, II, DL, get(RISCV::ADD), Acc)
3962 .addReg(Acc, RegState::Kill)
3963 .addReg(DestReg)
3964 .setMIFlag(Flag);
3965 }
3966 }
3967 PrevShiftAmount = ShiftAmount;
3968 }
3969 }
3970 assert(Acc && "Expected valid accumulator");
3971 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
3972 .addReg(DestReg, RegState::Kill)
3973 .addReg(Acc, RegState::Kill)
3974 .setMIFlag(Flag);
3975 }
3976}
3977
3980 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
3981 {{MONontemporalBit0, "riscv-nontemporal-domain-bit-0"},
3982 {MONontemporalBit1, "riscv-nontemporal-domain-bit-1"}};
3983 return ArrayRef(TargetFlags);
3984}
3985
3987 return OptLevel >= CodeGenOptLevel::Aggressive
3989 : 2;
3990}
3991
3992// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
3994 return MI.getOpcode() == RISCV::ADDIW && MI.getOperand(1).isReg() &&
3995 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0;
3996}
3997
3998// Returns true if this is the zext.w pattern, adduw rd, rs1, x0.
4000 return MI.getOpcode() == RISCV::ADD_UW && MI.getOperand(1).isReg() &&
4001 MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0;
4002}
4003
4004// Returns true if this is the zext.b pattern, andi rd, rs1, 255.
4006 return MI.getOpcode() == RISCV::ANDI && MI.getOperand(1).isReg() &&
4007 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 255;
4008}
4009
4010static bool isRVVWholeLoadStore(unsigned Opcode) {
4011 switch (Opcode) {
4012 default:
4013 return false;
4014 case RISCV::VS1R_V:
4015 case RISCV::VS2R_V:
4016 case RISCV::VS4R_V:
4017 case RISCV::VS8R_V:
4018 case RISCV::VL1RE8_V:
4019 case RISCV::VL2RE8_V:
4020 case RISCV::VL4RE8_V:
4021 case RISCV::VL8RE8_V:
4022 case RISCV::VL1RE16_V:
4023 case RISCV::VL2RE16_V:
4024 case RISCV::VL4RE16_V:
4025 case RISCV::VL8RE16_V:
4026 case RISCV::VL1RE32_V:
4027 case RISCV::VL2RE32_V:
4028 case RISCV::VL4RE32_V:
4029 case RISCV::VL8RE32_V:
4030 case RISCV::VL1RE64_V:
4031 case RISCV::VL2RE64_V:
4032 case RISCV::VL4RE64_V:
4033 case RISCV::VL8RE64_V:
4034 return true;
4035 }
4036}
4037
4039 // RVV lacks any support for immediate addressing for stack addresses, so be
4040 // conservative.
4041 unsigned Opcode = MI.getOpcode();
4042 if (!RISCVVPseudosTable::getPseudoInfo(Opcode) &&
4043 !isRVVWholeLoadStore(Opcode) && !isRVVSpillForZvlsseg(Opcode))
4044 return false;
4045 return true;
4046}
4047
4048std::optional<std::pair<unsigned, unsigned>>
4050 switch (Opcode) {
4051 default:
4052 return std::nullopt;
4053 case RISCV::PseudoVSPILL2_M1:
4054 case RISCV::PseudoVRELOAD2_M1:
4055 return std::make_pair(2u, 1u);
4056 case RISCV::PseudoVSPILL2_M2:
4057 case RISCV::PseudoVRELOAD2_M2:
4058 return std::make_pair(2u, 2u);
4059 case RISCV::PseudoVSPILL2_M4:
4060 case RISCV::PseudoVRELOAD2_M4:
4061 return std::make_pair(2u, 4u);
4062 case RISCV::PseudoVSPILL3_M1:
4063 case RISCV::PseudoVRELOAD3_M1:
4064 return std::make_pair(3u, 1u);
4065 case RISCV::PseudoVSPILL3_M2:
4066 case RISCV::PseudoVRELOAD3_M2:
4067 return std::make_pair(3u, 2u);
4068 case RISCV::PseudoVSPILL4_M1:
4069 case RISCV::PseudoVRELOAD4_M1:
4070 return std::make_pair(4u, 1u);
4071 case RISCV::PseudoVSPILL4_M2:
4072 case RISCV::PseudoVRELOAD4_M2:
4073 return std::make_pair(4u, 2u);
4074 case RISCV::PseudoVSPILL5_M1:
4075 case RISCV::PseudoVRELOAD5_M1:
4076 return std::make_pair(5u, 1u);
4077 case RISCV::PseudoVSPILL6_M1:
4078 case RISCV::PseudoVRELOAD6_M1:
4079 return std::make_pair(6u, 1u);
4080 case RISCV::PseudoVSPILL7_M1:
4081 case RISCV::PseudoVRELOAD7_M1:
4082 return std::make_pair(7u, 1u);
4083 case RISCV::PseudoVSPILL8_M1:
4084 case RISCV::PseudoVRELOAD8_M1:
4085 return std::make_pair(8u, 1u);
4086 }
4087}
4088
4090 return MI.getNumExplicitDefs() == 2 &&
4091 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) && !MI.isInlineAsm();
4092}
4093
4094bool RISCV::hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2) {
4095 int16_t MI1FrmOpIdx =
4096 RISCV::getNamedOperandIdx(MI1.getOpcode(), RISCV::OpName::frm);
4097 int16_t MI2FrmOpIdx =
4098 RISCV::getNamedOperandIdx(MI2.getOpcode(), RISCV::OpName::frm);
4099 if (MI1FrmOpIdx < 0 || MI2FrmOpIdx < 0)
4100 return false;
4101 MachineOperand FrmOp1 = MI1.getOperand(MI1FrmOpIdx);
4102 MachineOperand FrmOp2 = MI2.getOperand(MI2FrmOpIdx);
4103 return FrmOp1.getImm() == FrmOp2.getImm();
4104}
4105
4106std::optional<unsigned>
4108 // TODO: Handle Zvbb instructions
4109 switch (Opcode) {
4110 default:
4111 return std::nullopt;
4112
4113 // 11.6. Vector Single-Width Shift Instructions
4114 case RISCV::VSLL_VX:
4115 case RISCV::VSRL_VX:
4116 case RISCV::VSRA_VX:
4117 // 12.4. Vector Single-Width Scaling Shift Instructions
4118 case RISCV::VSSRL_VX:
4119 case RISCV::VSSRA_VX:
4120 // Only the low lg2(SEW) bits of the shift-amount value are used.
4121 return Log2SEW;
4122
4123 // 11.7 Vector Narrowing Integer Right Shift Instructions
4124 case RISCV::VNSRL_WX:
4125 case RISCV::VNSRA_WX:
4126 // 12.5. Vector Narrowing Fixed-Point Clip Instructions
4127 case RISCV::VNCLIPU_WX:
4128 case RISCV::VNCLIP_WX:
4129 // Only the low lg2(2*SEW) bits of the shift-amount value are used.
4130 return Log2SEW + 1;
4131
4132 // 11.1. Vector Single-Width Integer Add and Subtract
4133 case RISCV::VADD_VX:
4134 case RISCV::VSUB_VX:
4135 case RISCV::VRSUB_VX:
4136 // 11.2. Vector Widening Integer Add/Subtract
4137 case RISCV::VWADDU_VX:
4138 case RISCV::VWSUBU_VX:
4139 case RISCV::VWADD_VX:
4140 case RISCV::VWSUB_VX:
4141 case RISCV::VWADDU_WX:
4142 case RISCV::VWSUBU_WX:
4143 case RISCV::VWADD_WX:
4144 case RISCV::VWSUB_WX:
4145 // 11.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
4146 case RISCV::VADC_VXM:
4147 case RISCV::VADC_VIM:
4148 case RISCV::VMADC_VXM:
4149 case RISCV::VMADC_VIM:
4150 case RISCV::VMADC_VX:
4151 case RISCV::VSBC_VXM:
4152 case RISCV::VMSBC_VXM:
4153 case RISCV::VMSBC_VX:
4154 // 11.5 Vector Bitwise Logical Instructions
4155 case RISCV::VAND_VX:
4156 case RISCV::VOR_VX:
4157 case RISCV::VXOR_VX:
4158 // 11.8. Vector Integer Compare Instructions
4159 case RISCV::VMSEQ_VX:
4160 case RISCV::VMSNE_VX:
4161 case RISCV::VMSLTU_VX:
4162 case RISCV::VMSLT_VX:
4163 case RISCV::VMSLEU_VX:
4164 case RISCV::VMSLE_VX:
4165 case RISCV::VMSGTU_VX:
4166 case RISCV::VMSGT_VX:
4167 // 11.9. Vector Integer Min/Max Instructions
4168 case RISCV::VMINU_VX:
4169 case RISCV::VMIN_VX:
4170 case RISCV::VMAXU_VX:
4171 case RISCV::VMAX_VX:
4172 // 11.10. Vector Single-Width Integer Multiply Instructions
4173 case RISCV::VMUL_VX:
4174 case RISCV::VMULH_VX:
4175 case RISCV::VMULHU_VX:
4176 case RISCV::VMULHSU_VX:
4177 // 11.11. Vector Integer Divide Instructions
4178 case RISCV::VDIVU_VX:
4179 case RISCV::VDIV_VX:
4180 case RISCV::VREMU_VX:
4181 case RISCV::VREM_VX:
4182 // 11.12. Vector Widening Integer Multiply Instructions
4183 case RISCV::VWMUL_VX:
4184 case RISCV::VWMULU_VX:
4185 case RISCV::VWMULSU_VX:
4186 // 11.13. Vector Single-Width Integer Multiply-Add Instructions
4187 case RISCV::VMACC_VX:
4188 case RISCV::VNMSAC_VX:
4189 case RISCV::VMADD_VX:
4190 case RISCV::VNMSUB_VX:
4191 // 11.14. Vector Widening Integer Multiply-Add Instructions
4192 case RISCV::VWMACCU_VX:
4193 case RISCV::VWMACC_VX:
4194 case RISCV::VWMACCSU_VX:
4195 case RISCV::VWMACCUS_VX:
4196 // 11.15. Vector Integer Merge Instructions
4197 case RISCV::VMERGE_VXM:
4198 // 11.16. Vector Integer Move Instructions
4199 case RISCV::VMV_V_X:
4200 // 12.1. Vector Single-Width Saturating Add and Subtract
4201 case RISCV::VSADDU_VX:
4202 case RISCV::VSADD_VX:
4203 case RISCV::VSSUBU_VX:
4204 case RISCV::VSSUB_VX:
4205 // 12.2. Vector Single-Width Averaging Add and Subtract
4206 case RISCV::VAADDU_VX:
4207 case RISCV::VAADD_VX:
4208 case RISCV::VASUBU_VX:
4209 case RISCV::VASUB_VX:
4210 // 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
4211 case RISCV::VSMUL_VX:
4212 // 16.1. Integer Scalar Move Instructions
4213 case RISCV::VMV_S_X:
4214 return 1U << Log2SEW;
4215 }
4216}
4217
4218unsigned RISCV::getRVVMCOpcode(unsigned RVVPseudoOpcode) {
4220 RISCVVPseudosTable::getPseudoInfo(RVVPseudoOpcode);
4221 if (!RVV)
4222 return 0;
4223 return RVV->BaseInstr;
4224}
4225
4226unsigned RISCV::getDestLog2EEW(const MCInstrDesc &Desc, unsigned Log2SEW) {
4227 unsigned DestEEW =
4229 // EEW = 1
4230 if (DestEEW == 0)
4231 return 0;
4232 // EEW = SEW * n
4233 unsigned Scaled = Log2SEW + (DestEEW - 1);
4234 assert(Scaled >= 3 && Scaled <= 6);
4235 return Scaled;
4236}
4237
4238/// Given two VL operands, do we know that LHS <= RHS?
4240 if (LHS.isReg() && RHS.isReg() && LHS.getReg().isVirtual() &&
4241 LHS.getReg() == RHS.getReg())
4242 return true;
4243 if (RHS.isImm() && RHS.getImm() == RISCV::VLMaxSentinel)
4244 return true;
4245 if (LHS.isImm() && LHS.getImm() == RISCV::VLMaxSentinel)
4246 return false;
4247 if (!LHS.isImm() || !RHS.isImm())
4248 return false;
4249 return LHS.getImm() <= RHS.getImm();
4250}
4251
4252namespace {
4253class RISCVPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
4254 const MachineInstr *LHS;
4255 const MachineInstr *RHS;
4257
4258public:
4259 RISCVPipelinerLoopInfo(const MachineInstr *LHS, const MachineInstr *RHS,
4261 : LHS(LHS), RHS(RHS), Cond(Cond.begin(), Cond.end()) {}
4262
4263 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
4264 // Make the instructions for loop control be placed in stage 0.
4265 // The predecessors of LHS/RHS are considered by the caller.
4266 if (LHS && MI == LHS)
4267 return true;
4268 if (RHS && MI == RHS)
4269 return true;
4270 return false;
4271 }
4272
4273 std::optional<bool> createTripCountGreaterCondition(
4274 int TC, MachineBasicBlock &MBB,
4275 SmallVectorImpl<MachineOperand> &CondParam) override {
4276 // A branch instruction will be inserted as "if (Cond) goto epilogue".
4277 // Cond is normalized for such use.
4278 // The predecessors of the branch are assumed to have already been inserted.
4279 CondParam = Cond;
4280 return {};
4281 }
4282
4283 void setPreheader(MachineBasicBlock *NewPreheader) override {}
4284
4285 void adjustTripCount(int TripCountAdjust) override {}
4286
4287 void disposed() override {}
4288};
4289} // namespace
4290
4291std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
4293 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
4295 if (analyzeBranch(*LoopBB, TBB, FBB, Cond, /*AllowModify=*/false))
4296 return nullptr;
4297
4298 // Infinite loops are not supported
4299 if (TBB == LoopBB && FBB == LoopBB)
4300 return nullptr;
4301
4302 // Must be conditional branch
4303 if (FBB == nullptr)
4304 return nullptr;
4305
4306 assert((TBB == LoopBB || FBB == LoopBB) &&
4307 "The Loop must be a single-basic-block loop");
4308
4309 // Normalization for createTripCountGreaterCondition()
4310 if (TBB == LoopBB)
4312
4313 const MachineRegisterInfo &MRI = LoopBB->getParent()->getRegInfo();
4314 auto FindRegDef = [&MRI](MachineOperand &Op) -> const MachineInstr * {
4315 if (!Op.isReg())
4316 return nullptr;
4317 Register Reg = Op.getReg();
4318 if (!Reg.isVirtual())
4319 return nullptr;
4320 return MRI.getVRegDef(Reg);
4321 };
4322
4323 const MachineInstr *LHS = FindRegDef(Cond[1]);
4324 const MachineInstr *RHS = FindRegDef(Cond[2]);
4325 if (LHS && LHS->isPHI())
4326 return nullptr;
4327 if (RHS && RHS->isPHI())
4328 return nullptr;
4329
4330 return std::make_unique<RISCVPipelinerLoopInfo>(LHS, RHS, Cond);
4331}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg, unsigned NumRegs)
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc, unsigned ZeroReg=0, bool CheckZeroReg=false)
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
@ MachineOutlinerTailCall
Emit a save, restore, call, and return.
@ MachineOutlinerDefault
@ Scaled
static ARCCC::CondCode getOppositeBranchCondition(ARCCC::CondCode CC)
Return the inverse of passed condition, i.e. turning COND_E to COND_NE.
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
basic Basic Alias true
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:686
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
#define _
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
static M68k::CondCode getCondFromBranchOpc(unsigned BrOpc)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static bool cannotInsertTailCall(const MachineBasicBlock &MBB)
#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP)
static bool isRVVWholeLoadStore(unsigned Opcode)
#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP)
static unsigned getFPFusedMultiplyOpcode(unsigned RootOpc, unsigned Pattern)
#define RVV_OPC_LMUL_CASE(OPC, INV)
static void combineFPFusedMultiply(MachineInstr &Root, MachineInstr &Prev, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs)
static unsigned getAddendOperandIdx(unsigned Pattern)
#define CASE_RVV_OPCODE_UNMASK(OP)
#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP)
static std::optional< MachineOutlinerConstructionID > analyzeCandidate(outliner::Candidate &C)
static cl::opt< bool > PreferWholeRegisterMove("riscv-prefer-whole-register-move", cl::init(false), cl::Hidden, cl::desc("Prefer whole register move for vector registers."))
#define CASE_VFMA_SPLATS(OP)
unsigned getPredicatedOpcode(unsigned Opcode)
static void genShXAddAddShift(MachineInstr &Root, unsigned AddOpIdx, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< unsigned, unsigned > &InstrIdxForVirtReg)
#define CASE_WIDEOP_OPCODE_LMULS(OP)
#define OPCODE_LMUL_MASK_CASE(OPC)
static bool isFSUB(unsigned Opc)
#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE)
#define CASE_RVV_OPCODE(OP)
#define CASE_VFMA_OPCODE_VV(OP)
MachineOutlinerConstructionID
#define CASE_RVV_OPCODE_WIDEN(OP)
#define CASE_VMA_OPCODE_LMULS(OP, TYPE)
static bool isFMUL(unsigned Opc)
static bool getFPPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce)
#define OPCODE_LMUL_CASE(OPC)
#define CASE_OPERAND_UIMM(NUM)
static bool canCombineShiftIntoShXAdd(const MachineBasicBlock &MBB, const MachineOperand &MO, unsigned OuterShiftAmt)
Utility routine that checks if.
static bool isCandidatePatchable(const MachineBasicBlock &MBB)
static bool isMIReadsReg(const MachineInstr &MI, const TargetRegisterInfo *TRI, unsigned RegNo)
static bool isFADD(unsigned Opc)
#define CASE_FP_WIDEOP_OPCODE_LMULS_MF4(OP)
static bool isConvertibleToVMV_V_V(const RISCVSubtarget &STI, const MachineBasicBlock &MBB, MachineBasicBlock::const_iterator MBBI, MachineBasicBlock::const_iterator &DefMBBI, RISCVII::VLMUL LMul)
static bool isMIModifiesReg(const MachineInstr &MI, const TargetRegisterInfo *TRI, unsigned RegNo)
static MachineInstr * canFoldAsPredicatedOp(Register Reg, const MachineRegisterInfo &MRI, const TargetInstrInfo *TII)
Identify instructions that can be folded into a CCMOV instruction, and return the defining instructio...
static bool canCombineFPFusedMultiply(const MachineInstr &Root, const MachineOperand &MO, bool DoRegPressureReduce)
static bool getSHXADDPatterns(const MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns)
static bool getFPFusedMultiplyPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce)
static cl::opt< MachineTraceStrategy > ForceMachineCombinerStrategy("riscv-force-machine-combiner-strategy", cl::Hidden, cl::desc("Force machine combiner to use a specific strategy for machine " "trace metrics evaluation."), cl::init(MachineTraceStrategy::TS_NumStrategies), cl::values(clEnumValN(MachineTraceStrategy::TS_Local, "local", "Local strategy."), clEnumValN(MachineTraceStrategy::TS_MinInstrCount, "min-instr", "MinInstrCount strategy.")))
static unsigned getSHXADDShiftAmount(unsigned Opc)
#define CASE_RVV_OPCODE_MASK(OP)
#define RVV_OPC_LMUL_MASK_CASE(OPC, INV)
#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP)
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
This file defines the SmallVector class.
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
static unsigned getSize(unsigned Kind)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
const T & front() const
front - Get the first element.
Definition: ArrayRef.h:171
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:168
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:163
static DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
This class represents an Operation in the Expression.
bool isBigEndian() const
Definition: DataLayout.h:198
A debug info location.
Definition: DebugLoc.h:33
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:211
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition: Function.h:704
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:687
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.
Definition: LiveInterval.h:408
void replaceKillInstruction(Register Reg, MachineInstr &OldMI, MachineInstr &NewMI)
replaceKillInstruction - Update register kill info by replacing a kill instruction with a new one.
bool hasValue() const
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
TypeSize getValue() const
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
Definition: MCInstBuilder.h:37
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:43
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:237
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
Definition: MCInstrDesc.h:317
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:85
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:97
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
const FeatureBitset & getFeatureBits() const
Set of metadata that should be preserved when using BuildMI().
unsigned pred_size() const
reverse_iterator rend()
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
Instructions::const_iterator const_instr_iterator
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setStackID(int ObjectIdx, uint8_t ID)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
Definition: MachineInstr.h:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:575
bool isReturn(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:946
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:347
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
Definition: MachineInstr.h:397
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
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.
Definition: MachineInstr.h:572
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.
Definition: MachineInstr.h:821
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:806
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
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.
Definition: MachineInstr.h:788
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:499
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:585
uint32_t getFlags() const
Return the MI flags bitvector.
Definition: MachineInstr.h:392
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.
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.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
MI-level patchpoint operands.
Definition: StackMaps.h:76
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Definition: StackMaps.h:104
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, LiveIntervals *LIS) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
std::optional< std::unique_ptr< outliner::OutlinedFunction > > getOutliningCandidateInfo(const MachineModuleInfo &MMI, std::vector< outliner::Candidate > &RepeatedSequenceLocs, unsigned MinRepeats) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
void 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...
bool isReallyTriviallyReMaterializable(const MachineInstr &MI) const override
bool isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) const override
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &dl, int *BytesAdded=nullptr) const override
bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) const override
RISCVInstrInfo(RISCVSubtarget &STI)
void copyPhysRegVector(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc, const TargetRegisterClass *RegClass) const
void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< unsigned, unsigned > &InstrIdxForVirtReg) const override
const MCInstrDesc & getBrCond(RISCVCC::CondCode CC, bool Imm=false) const
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, const MachineInstr &AddrI, ExtAddrMode &AM) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
bool isAsCheapAsAMove(const MachineInstr &MI) const override
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
unsigned getTailDuplicateSize(CodeGenOptLevel OptLevel) const override
void getReassociateOperandIndices(const MachineInstr &Root, unsigned Pattern, std::array< unsigned, 5 > &OperandIndices) const override
const RISCVSubtarget & STI
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
virtual outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI, MachineBasicBlock::iterator &MBBI, unsigned Flags) const override
MachineTraceStrategy getMachineCombinerTraceStrategy() const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
std::optional< RegImmPair > isAddImmediate(const MachineInstr &MI, Register Reg) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
ArrayRef< std::pair< MachineMemOperand::Flags, const char * > > getSerializableMachineMemOperandTargetFlags() const override
MCInst getNop() const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &MI, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override
void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
bool hasReassociableOperands(const MachineInstr &Inst, const MachineBasicBlock *MBB) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const override
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
CombinerObjective getCombinerObjective(unsigned Pattern) const override
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const override
bool optimizeCondBranch(MachineInstr &MI) const override
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
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
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
bool hasStdExtCOrZca() const
unsigned getTailDupAggressiveThreshold() const
unsigned getXLen() const
const RISCVRegisterInfo * getRegisterInfo() const override
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
void setRegUsed(Register Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
Register scavengeRegisterBackwards(const TargetRegisterClass &RC, MachineBasicBlock::iterator To, bool RestoreAfter, int SPAdj, bool AllowSpill=true)
Make a register of the specific register class available from the current position backwards to the p...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isValid() const
Definition: Register.h:116
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:65
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:363
bool erase(PtrType Ptr)
Remove pointer from the set.
Definition: SmallPtrSet.h:401
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:384
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
MI-level stackmap operands.
Definition: StackMaps.h:35
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
Definition: StackMaps.h:50
MI-level Statepoint operands.
Definition: StackMaps.h:158
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given statepoint should emit.
Definition: StackMaps.h:207
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
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< unsigned, unsigned > &InstIdxForVirtReg) const
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
virtual bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for an instruction chain ending in Root.
virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const
Optional target hook that returns true if MBB is safe to outline from, and returns any target-specifi...
virtual void getReassociateOperandIndices(const MachineInstr &Root, unsigned Pattern, std::array< unsigned, 5 > &OperandIndices) const
The returned array encodes the operand index for each parameter because the operands may be commuted;...
virtual bool isReallyTriviallyReMaterializable(const MachineInstr &MI) const
For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...
virtual CombinerObjective getCombinerObjective(unsigned Pattern) const
Return the objective of a combiner pattern.
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
virtual bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) const
Return true when \P Inst has reassociable sibling.
virtual std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
const uint8_t TSFlags
Configurable target specific flags.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
Target - Wrapper for Target specific information.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
#define INT64_MAX
Definition: DataTypes.h:71
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
CondCode getOppositeBranchCondition(CondCode)
unsigned getBrCond(CondCode CC, bool Imm=false)
static bool isValidRoundingMode(unsigned Mode)
static unsigned getVecPolicyOpNum(const MCInstrDesc &Desc)
static bool usesMaskPolicy(uint64_t TSFlags)
static bool hasRoundModeOp(uint64_t TSFlags)
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static bool hasVLOp(uint64_t TSFlags)
static int getFRMOpNum(const MCInstrDesc &Desc)
static bool hasVecPolicyOp(uint64_t TSFlags)
static bool usesVXRM(uint64_t TSFlags)
static unsigned getTailExpandUseRegNo(const FeatureBitset &FeatureBits)
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)
@ OPERAND_UIMMLOG2XLEN_NONZERO
@ OPERAND_UIMM10_LSB00_NONZERO
@ OPERAND_SIMM10_LSB0000_NONZERO
static RISCVII::VLMUL getLMul(uint64_t TSFlags)
static unsigned getNF(uint64_t TSFlags)
static bool isTailAgnostic(unsigned VType)
static RISCVII::VLMUL getVLMUL(unsigned VType)
std::pair< unsigned, bool > decodeVLMUL(RISCVII::VLMUL VLMUL)
static bool isValidSEW(unsigned SEW)
void printVType(unsigned VType, raw_ostream &OS)
static unsigned getSEW(unsigned VType)
bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2)
bool isVLKnownLE(const MachineOperand &LHS, const MachineOperand &RHS)
Given two VL operands, do we know that LHS <= RHS?
std::optional< unsigned > getVectorLowDemandedScalarBits(uint16_t Opcode, unsigned Log2SEW)
int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex)
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
unsigned getDestLog2EEW(const MCInstrDesc &Desc, unsigned Log2SEW)
bool isSEXT_W(const MachineInstr &MI)
bool isFaultFirstLoad(const MachineInstr &MI)
std::optional< std::pair< unsigned, unsigned > > isRVVSpillForZvlsseg(unsigned Opcode)
bool isZEXT_B(const MachineInstr &MI)
bool isRVVSpill(const MachineInstr &MI)
static constexpr int64_t VLMaxSentinel
bool isZEXT_W(const MachineInstr &MI)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Dead
Unused definition.
@ Define
Register definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Definition: CommandLine.h:711
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
InstrType
Represents how an instruction should be mapped by the outliner.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
@ Offset
Definition: DWP.cpp:480
@ SHXADD_ADD_SLLI_OP2
@ FMADD_AX
@ FMADD_XA
@ SHXADD_ADD_SLLI_OP1
MachineTraceStrategy
Strategies for selecting traces.
@ TS_MinInstrCount
Select the trace through a block that has the fewest instructions.
@ TS_Local
Select the trace that contains only the current basic block.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1739
static const MachineMemOperand::Flags MONontemporalBit1
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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:2448
static const MachineMemOperand::Flags MONontemporalBit0
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
unsigned getDeadRegState(bool B)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:296
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:346
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:340
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
unsigned getKillRegState(bool B)
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:260
unsigned getRenamableRegState(bool B)
DWARFExpression::Operation Op
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:581
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
#define N
Description of the encoding of one expression Op.
Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
This represents a simple continuous liveness interval for a value.
Definition: LiveInterval.h:162
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
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.
unsigned FrameConstructionID
Target-defined identifier for constructing a frame for this function.