LLVM 19.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"
15#include "RISCV.h"
17#include "RISCVSubtarget.h"
18#include "RISCVTargetMachine.h"
19#include "llvm/ADT/STLExtras.h"
33#include "llvm/IR/Module.h"
37
38using namespace llvm;
39
40#define GEN_CHECK_COMPRESS_INSTR
41#include "RISCVGenCompressInstEmitter.inc"
42
43#define GET_INSTRINFO_CTOR_DTOR
44#define GET_INSTRINFO_NAMED_OPS
45#include "RISCVGenInstrInfo.inc"
46
48 "riscv-prefer-whole-register-move", cl::init(false), cl::Hidden,
49 cl::desc("Prefer whole register move for vector registers."));
50
52 "riscv-force-machine-combiner-strategy", cl::Hidden,
53 cl::desc("Force machine combiner to use a specific strategy for machine "
54 "trace metrics evaluation."),
55 cl::init(MachineTraceStrategy::TS_NumStrategies),
56 cl::values(clEnumValN(MachineTraceStrategy::TS_Local, "local",
57 "Local strategy."),
58 clEnumValN(MachineTraceStrategy::TS_MinInstrCount, "min-instr",
59 "MinInstrCount strategy.")));
60
62
63using namespace RISCV;
64
65#define GET_RISCVVPseudosTable_IMPL
66#include "RISCVGenSearchableTables.inc"
67
68} // namespace llvm::RISCVVPseudosTable
69
70namespace llvm::RISCV {
71
72#define GET_RISCVMaskedPseudosTable_IMPL
73#include "RISCVGenSearchableTables.inc"
74
75} // end namespace llvm::RISCV
76
78 : RISCVGenInstrInfo(RISCV::ADJCALLSTACKDOWN, RISCV::ADJCALLSTACKUP),
79 STI(STI) {}
80
82 if (STI.hasStdExtCOrZca())
83 return MCInstBuilder(RISCV::C_NOP);
84 return MCInstBuilder(RISCV::ADDI)
85 .addReg(RISCV::X0)
86 .addReg(RISCV::X0)
87 .addImm(0);
88}
89
91 int &FrameIndex) const {
92 unsigned Dummy;
93 return isLoadFromStackSlot(MI, FrameIndex, Dummy);
94}
95
97 int &FrameIndex,
98 unsigned &MemBytes) const {
99 switch (MI.getOpcode()) {
100 default:
101 return 0;
102 case RISCV::LB:
103 case RISCV::LBU:
104 MemBytes = 1;
105 break;
106 case RISCV::LH:
107 case RISCV::LHU:
108 case RISCV::FLH:
109 MemBytes = 2;
110 break;
111 case RISCV::LW:
112 case RISCV::FLW:
113 case RISCV::LWU:
114 MemBytes = 4;
115 break;
116 case RISCV::LD:
117 case RISCV::FLD:
118 MemBytes = 8;
119 break;
120 }
121
122 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
123 MI.getOperand(2).getImm() == 0) {
124 FrameIndex = MI.getOperand(1).getIndex();
125 return MI.getOperand(0).getReg();
126 }
127
128 return 0;
129}
130
132 int &FrameIndex) const {
133 unsigned Dummy;
134 return isStoreToStackSlot(MI, FrameIndex, Dummy);
135}
136
138 int &FrameIndex,
139 unsigned &MemBytes) const {
140 switch (MI.getOpcode()) {
141 default:
142 return 0;
143 case RISCV::SB:
144 MemBytes = 1;
145 break;
146 case RISCV::SH:
147 case RISCV::FSH:
148 MemBytes = 2;
149 break;
150 case RISCV::SW:
151 case RISCV::FSW:
152 MemBytes = 4;
153 break;
154 case RISCV::SD:
155 case RISCV::FSD:
156 MemBytes = 8;
157 break;
158 }
159
160 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
161 MI.getOperand(2).getImm() == 0) {
162 FrameIndex = MI.getOperand(1).getIndex();
163 return MI.getOperand(0).getReg();
164 }
165
166 return 0;
167}
168
169static bool forwardCopyWillClobberTuple(unsigned DstReg, unsigned SrcReg,
170 unsigned NumRegs) {
171 return DstReg > SrcReg && (DstReg - SrcReg) < NumRegs;
172}
173
175 const MachineBasicBlock &MBB,
178 RISCVII::VLMUL LMul) {
180 return false;
181
182 assert(MBBI->getOpcode() == TargetOpcode::COPY &&
183 "Unexpected COPY instruction.");
184 Register SrcReg = MBBI->getOperand(1).getReg();
186
187 bool FoundDef = false;
188 bool FirstVSetVLI = false;
189 unsigned FirstSEW = 0;
190 while (MBBI != MBB.begin()) {
191 --MBBI;
192 if (MBBI->isMetaInstruction())
193 continue;
194
195 if (MBBI->getOpcode() == RISCV::PseudoVSETVLI ||
196 MBBI->getOpcode() == RISCV::PseudoVSETVLIX0 ||
197 MBBI->getOpcode() == RISCV::PseudoVSETIVLI) {
198 // There is a vsetvli between COPY and source define instruction.
199 // vy = def_vop ... (producing instruction)
200 // ...
201 // vsetvli
202 // ...
203 // vx = COPY vy
204 if (!FoundDef) {
205 if (!FirstVSetVLI) {
206 FirstVSetVLI = true;
207 unsigned FirstVType = MBBI->getOperand(2).getImm();
208 RISCVII::VLMUL FirstLMul = RISCVVType::getVLMUL(FirstVType);
209 FirstSEW = RISCVVType::getSEW(FirstVType);
210 // The first encountered vsetvli must have the same lmul as the
211 // register class of COPY.
212 if (FirstLMul != LMul)
213 return false;
214 }
215 // Only permit `vsetvli x0, x0, vtype` between COPY and the source
216 // define instruction.
217 if (MBBI->getOperand(0).getReg() != RISCV::X0)
218 return false;
219 if (MBBI->getOperand(1).isImm())
220 return false;
221 if (MBBI->getOperand(1).getReg() != RISCV::X0)
222 return false;
223 continue;
224 }
225
226 // MBBI is the first vsetvli before the producing instruction.
227 unsigned VType = MBBI->getOperand(2).getImm();
228 // If there is a vsetvli between COPY and the producing instruction.
229 if (FirstVSetVLI) {
230 // If SEW is different, return false.
231 if (RISCVVType::getSEW(VType) != FirstSEW)
232 return false;
233 }
234
235 // If the vsetvli is tail undisturbed, keep the whole register move.
236 if (!RISCVVType::isTailAgnostic(VType))
237 return false;
238
239 // The checking is conservative. We only have register classes for
240 // LMUL = 1/2/4/8. We should be able to convert vmv1r.v to vmv.v.v
241 // for fractional LMUL operations. However, we could not use the vsetvli
242 // lmul for widening operations. The result of widening operation is
243 // 2 x LMUL.
244 return LMul == RISCVVType::getVLMUL(VType);
245 } else if (MBBI->isInlineAsm() || MBBI->isCall()) {
246 return false;
247 } else if (MBBI->getNumDefs()) {
248 // Check all the instructions which will change VL.
249 // For example, vleff has implicit def VL.
250 if (MBBI->modifiesRegister(RISCV::VL, /*TRI=*/nullptr))
251 return false;
252
253 // Only converting whole register copies to vmv.v.v when the defining
254 // value appears in the explicit operands.
255 for (const MachineOperand &MO : MBBI->explicit_operands()) {
256 if (!MO.isReg() || !MO.isDef())
257 continue;
258 if (!FoundDef && TRI->regsOverlap(MO.getReg(), SrcReg)) {
259 // We only permit the source of COPY has the same LMUL as the defined
260 // operand.
261 // There are cases we need to keep the whole register copy if the LMUL
262 // is different.
263 // For example,
264 // $x0 = PseudoVSETIVLI 4, 73 // vsetivli zero, 4, e16,m2,ta,m
265 // $v28m4 = PseudoVWADD_VV_M2 $v26m2, $v8m2
266 // # The COPY may be created by vlmul_trunc intrinsic.
267 // $v26m2 = COPY renamable $v28m2, implicit killed $v28m4
268 //
269 // After widening, the valid value will be 4 x e32 elements. If we
270 // convert the COPY to vmv.v.v, it will only copy 4 x e16 elements.
271 // FIXME: The COPY of subregister of Zvlsseg register will not be able
272 // to convert to vmv.v.[v|i] under the constraint.
273 if (MO.getReg() != SrcReg)
274 return false;
275
276 // In widening reduction instructions with LMUL_1 input vector case,
277 // only checking the LMUL is insufficient due to reduction result is
278 // always LMUL_1.
279 // For example,
280 // $x11 = PseudoVSETIVLI 1, 64 // vsetivli a1, 1, e8, m1, ta, mu
281 // $v8m1 = PseudoVWREDSUM_VS_M1 $v26, $v27
282 // $v26 = COPY killed renamable $v8
283 // After widening, The valid value will be 1 x e16 elements. If we
284 // convert the COPY to vmv.v.v, it will only copy 1 x e8 elements.
285 uint64_t TSFlags = MBBI->getDesc().TSFlags;
287 return false;
288
289 // If the producing instruction does not depend on vsetvli, do not
290 // convert COPY to vmv.v.v. For example, VL1R_V or PseudoVRELOAD.
291 if (!RISCVII::hasSEWOp(TSFlags) || !RISCVII::hasVLOp(TSFlags))
292 return false;
293
294 // Found the definition.
295 FoundDef = true;
296 DefMBBI = MBBI;
297 break;
298 }
299 }
300 }
301 }
302
303 return false;
304}
305
308 const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc,
309 const TargetRegisterClass *RegClass) const {
311 RISCVII::VLMUL LMul = RISCVRI::getLMul(RegClass->TSFlags);
312 unsigned NF = RISCVRI::getNF(RegClass->TSFlags);
313
314 uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
315 uint16_t DstEncoding = TRI->getEncodingValue(DstReg);
316 auto [LMulVal, Fractional] = RISCVVType::decodeVLMUL(LMul);
317 assert(!Fractional && "It is impossible be fractional lmul here.");
318 unsigned NumRegs = NF * LMulVal;
319 bool ReversedCopy =
320 forwardCopyWillClobberTuple(DstEncoding, SrcEncoding, NumRegs);
321 if (ReversedCopy) {
322 // If the src and dest overlap when copying a tuple, we need to copy the
323 // registers in reverse.
324 SrcEncoding += NumRegs - 1;
325 DstEncoding += NumRegs - 1;
326 }
327
328 unsigned I = 0;
329 auto GetCopyInfo = [&](uint16_t SrcEncoding, uint16_t DstEncoding)
330 -> std::tuple<RISCVII::VLMUL, const TargetRegisterClass &, unsigned,
331 unsigned, unsigned> {
332 if (ReversedCopy) {
333 // For reversed copying, if there are enough aligned registers(8/4/2), we
334 // can do a larger copy(LMUL8/4/2).
335 // Besides, we have already known that DstEncoding is larger than
336 // SrcEncoding in forwardCopyWillClobberTuple, so the difference between
337 // DstEncoding and SrcEncoding should be >= LMUL value we try to use to
338 // avoid clobbering.
339 uint16_t Diff = DstEncoding - SrcEncoding;
340 if (I + 8 <= NumRegs && Diff >= 8 && SrcEncoding % 8 == 7 &&
341 DstEncoding % 8 == 7)
342 return {RISCVII::LMUL_8, RISCV::VRM8RegClass, RISCV::VMV8R_V,
343 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
344 if (I + 4 <= NumRegs && Diff >= 4 && SrcEncoding % 4 == 3 &&
345 DstEncoding % 4 == 3)
346 return {RISCVII::LMUL_4, RISCV::VRM4RegClass, RISCV::VMV4R_V,
347 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
348 if (I + 2 <= NumRegs && Diff >= 2 && SrcEncoding % 2 == 1 &&
349 DstEncoding % 2 == 1)
350 return {RISCVII::LMUL_2, RISCV::VRM2RegClass, RISCV::VMV2R_V,
351 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
352 // Or we should do LMUL1 copying.
353 return {RISCVII::LMUL_1, RISCV::VRRegClass, RISCV::VMV1R_V,
354 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
355 }
356
357 // For forward copying, if source register encoding and destination register
358 // encoding are aligned to 8/4/2, we can do a LMUL8/4/2 copying.
359 if (I + 8 <= NumRegs && SrcEncoding % 8 == 0 && DstEncoding % 8 == 0)
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 && SrcEncoding % 4 == 0 && DstEncoding % 4 == 0)
363 return {RISCVII::LMUL_4, RISCV::VRM4RegClass, RISCV::VMV4R_V,
364 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
365 if (I + 2 <= NumRegs && SrcEncoding % 2 == 0 && DstEncoding % 2 == 0)
366 return {RISCVII::LMUL_2, RISCV::VRM2RegClass, RISCV::VMV2R_V,
367 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
368 // Or we should do LMUL1 copying.
369 return {RISCVII::LMUL_1, RISCV::VRRegClass, RISCV::VMV1R_V,
370 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
371 };
372 auto FindRegWithEncoding = [TRI](const TargetRegisterClass &RegClass,
373 uint16_t Encoding) {
374 MCRegister Reg = RISCV::V0 + Encoding;
375 if (&RegClass == &RISCV::VRRegClass)
376 return Reg;
377 return TRI->getMatchingSuperReg(Reg, RISCV::sub_vrm1_0, &RegClass);
378 };
379 while (I != NumRegs) {
380 // For non-segment copying, we only do this once as the registers are always
381 // aligned.
382 // For segment copying, we may do this several times. If the registers are
383 // aligned to larger LMUL, we can eliminate some copyings.
384 auto [LMulCopied, RegClass, Opc, VVOpc, VIOpc] =
385 GetCopyInfo(SrcEncoding, DstEncoding);
386 auto [NumCopied, _] = RISCVVType::decodeVLMUL(LMulCopied);
387
389 if (LMul == LMulCopied &&
390 isConvertibleToVMV_V_V(STI, MBB, MBBI, DefMBBI, LMul)) {
391 Opc = VVOpc;
392 if (DefMBBI->getOpcode() == VIOpc)
393 Opc = VIOpc;
394 }
395
396 // Emit actual copying.
397 // For reversed copying, the encoding should be decreased.
398 MCRegister ActualSrcReg = FindRegWithEncoding(
399 RegClass, ReversedCopy ? (SrcEncoding - NumCopied + 1) : SrcEncoding);
400 MCRegister ActualDstReg = FindRegWithEncoding(
401 RegClass, ReversedCopy ? (DstEncoding - NumCopied + 1) : DstEncoding);
402
403 auto MIB = BuildMI(MBB, MBBI, DL, get(Opc), ActualDstReg);
404 bool UseVMV_V_I = RISCV::getRVVMCOpcode(Opc) == RISCV::VMV_V_I;
405 bool UseVMV = UseVMV_V_I || RISCV::getRVVMCOpcode(Opc) == RISCV::VMV_V_V;
406 if (UseVMV)
407 MIB.addReg(ActualDstReg, RegState::Undef);
408 if (UseVMV_V_I)
409 MIB = MIB.add(DefMBBI->getOperand(2));
410 else
411 MIB = MIB.addReg(ActualSrcReg, getKillRegState(KillSrc));
412 if (UseVMV) {
413 const MCInstrDesc &Desc = DefMBBI->getDesc();
414 MIB.add(DefMBBI->getOperand(RISCVII::getVLOpNum(Desc))); // AVL
415 MIB.add(DefMBBI->getOperand(RISCVII::getSEWOpNum(Desc))); // SEW
416 MIB.addImm(0); // tu, mu
417 MIB.addReg(RISCV::VL, RegState::Implicit);
418 MIB.addReg(RISCV::VTYPE, RegState::Implicit);
419 }
420
421 // If we are copying reversely, we should decrease the encoding.
422 SrcEncoding += (ReversedCopy ? -NumCopied : NumCopied);
423 DstEncoding += (ReversedCopy ? -NumCopied : NumCopied);
424 I += NumCopied;
425 }
426}
427
430 const DebugLoc &DL, MCRegister DstReg,
431 MCRegister SrcReg, bool KillSrc) const {
433
434 if (RISCV::GPRRegClass.contains(DstReg, SrcReg)) {
435 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg)
436 .addReg(SrcReg, getKillRegState(KillSrc))
437 .addImm(0);
438 return;
439 }
440
441 if (RISCV::GPRPairRegClass.contains(DstReg, SrcReg)) {
442 // Emit an ADDI for both parts of GPRPair.
443 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI),
444 TRI->getSubReg(DstReg, RISCV::sub_gpr_even))
445 .addReg(TRI->getSubReg(SrcReg, RISCV::sub_gpr_even),
446 getKillRegState(KillSrc))
447 .addImm(0);
448 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI),
449 TRI->getSubReg(DstReg, RISCV::sub_gpr_odd))
450 .addReg(TRI->getSubReg(SrcReg, RISCV::sub_gpr_odd),
451 getKillRegState(KillSrc))
452 .addImm(0);
453 return;
454 }
455
456 // Handle copy from csr
457 if (RISCV::VCSRRegClass.contains(SrcReg) &&
458 RISCV::GPRRegClass.contains(DstReg)) {
459 BuildMI(MBB, MBBI, DL, get(RISCV::CSRRS), DstReg)
460 .addImm(RISCVSysReg::lookupSysRegByName(TRI->getName(SrcReg))->Encoding)
461 .addReg(RISCV::X0);
462 return;
463 }
464
465 if (RISCV::FPR16RegClass.contains(DstReg, SrcReg)) {
466 unsigned Opc;
467 if (STI.hasStdExtZfh()) {
468 Opc = RISCV::FSGNJ_H;
469 } else {
470 assert(STI.hasStdExtF() &&
471 (STI.hasStdExtZfhmin() || STI.hasStdExtZfbfmin()) &&
472 "Unexpected extensions");
473 // Zfhmin/Zfbfmin doesn't have FSGNJ_H, replace FSGNJ_H with FSGNJ_S.
474 DstReg = TRI->getMatchingSuperReg(DstReg, RISCV::sub_16,
475 &RISCV::FPR32RegClass);
476 SrcReg = TRI->getMatchingSuperReg(SrcReg, RISCV::sub_16,
477 &RISCV::FPR32RegClass);
478 Opc = RISCV::FSGNJ_S;
479 }
480 BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
481 .addReg(SrcReg, getKillRegState(KillSrc))
482 .addReg(SrcReg, getKillRegState(KillSrc));
483 return;
484 }
485
486 if (RISCV::FPR32RegClass.contains(DstReg, SrcReg)) {
487 BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_S), DstReg)
488 .addReg(SrcReg, getKillRegState(KillSrc))
489 .addReg(SrcReg, getKillRegState(KillSrc));
490 return;
491 }
492
493 if (RISCV::FPR64RegClass.contains(DstReg, SrcReg)) {
494 BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_D), DstReg)
495 .addReg(SrcReg, getKillRegState(KillSrc))
496 .addReg(SrcReg, getKillRegState(KillSrc));
497 return;
498 }
499
500 if (RISCV::FPR32RegClass.contains(DstReg) &&
501 RISCV::GPRRegClass.contains(SrcReg)) {
502 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_W_X), DstReg)
503 .addReg(SrcReg, getKillRegState(KillSrc));
504 return;
505 }
506
507 if (RISCV::GPRRegClass.contains(DstReg) &&
508 RISCV::FPR32RegClass.contains(SrcReg)) {
509 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_X_W), DstReg)
510 .addReg(SrcReg, getKillRegState(KillSrc));
511 return;
512 }
513
514 if (RISCV::FPR64RegClass.contains(DstReg) &&
515 RISCV::GPRRegClass.contains(SrcReg)) {
516 assert(STI.getXLen() == 64 && "Unexpected GPR size");
517 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_D_X), DstReg)
518 .addReg(SrcReg, getKillRegState(KillSrc));
519 return;
520 }
521
522 if (RISCV::GPRRegClass.contains(DstReg) &&
523 RISCV::FPR64RegClass.contains(SrcReg)) {
524 assert(STI.getXLen() == 64 && "Unexpected GPR size");
525 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_X_D), DstReg)
526 .addReg(SrcReg, getKillRegState(KillSrc));
527 return;
528 }
529
530 // VR->VR copies.
531 static const TargetRegisterClass *RVVRegClasses[] = {
532 &RISCV::VRRegClass, &RISCV::VRM2RegClass, &RISCV::VRM4RegClass,
533 &RISCV::VRM8RegClass, &RISCV::VRN2M1RegClass, &RISCV::VRN2M2RegClass,
534 &RISCV::VRN2M4RegClass, &RISCV::VRN3M1RegClass, &RISCV::VRN3M2RegClass,
535 &RISCV::VRN4M1RegClass, &RISCV::VRN4M2RegClass, &RISCV::VRN5M1RegClass,
536 &RISCV::VRN6M1RegClass, &RISCV::VRN7M1RegClass, &RISCV::VRN8M1RegClass};
537 for (const auto &RegClass : RVVRegClasses) {
538 if (RegClass->contains(DstReg, SrcReg)) {
539 copyPhysRegVector(MBB, MBBI, DL, DstReg, SrcReg, KillSrc, RegClass);
540 return;
541 }
542 }
543
544 llvm_unreachable("Impossible reg-to-reg copy");
545}
546
549 Register SrcReg, bool IsKill, int FI,
550 const TargetRegisterClass *RC,
551 const TargetRegisterInfo *TRI,
552 Register VReg) const {
554 MachineFrameInfo &MFI = MF->getFrameInfo();
555
556 unsigned Opcode;
557 bool IsScalableVector = true;
558 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
559 Opcode = TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
560 RISCV::SW : RISCV::SD;
561 IsScalableVector = false;
562 } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
563 Opcode = RISCV::PseudoRV32ZdinxSD;
564 IsScalableVector = false;
565 } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
566 Opcode = RISCV::FSH;
567 IsScalableVector = false;
568 } else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
569 Opcode = RISCV::FSW;
570 IsScalableVector = false;
571 } else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
572 Opcode = RISCV::FSD;
573 IsScalableVector = false;
574 } else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
575 Opcode = RISCV::VS1R_V;
576 } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
577 Opcode = RISCV::VS2R_V;
578 } else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
579 Opcode = RISCV::VS4R_V;
580 } else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
581 Opcode = RISCV::VS8R_V;
582 } else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
583 Opcode = RISCV::PseudoVSPILL2_M1;
584 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
585 Opcode = RISCV::PseudoVSPILL2_M2;
586 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
587 Opcode = RISCV::PseudoVSPILL2_M4;
588 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
589 Opcode = RISCV::PseudoVSPILL3_M1;
590 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
591 Opcode = RISCV::PseudoVSPILL3_M2;
592 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
593 Opcode = RISCV::PseudoVSPILL4_M1;
594 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
595 Opcode = RISCV::PseudoVSPILL4_M2;
596 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
597 Opcode = RISCV::PseudoVSPILL5_M1;
598 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
599 Opcode = RISCV::PseudoVSPILL6_M1;
600 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
601 Opcode = RISCV::PseudoVSPILL7_M1;
602 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
603 Opcode = RISCV::PseudoVSPILL8_M1;
604 else
605 llvm_unreachable("Can't store this register to stack slot");
606
607 if (IsScalableVector) {
611
613 BuildMI(MBB, I, DebugLoc(), get(Opcode))
614 .addReg(SrcReg, getKillRegState(IsKill))
615 .addFrameIndex(FI)
616 .addMemOperand(MMO);
617 } else {
620 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
621
622 BuildMI(MBB, I, DebugLoc(), get(Opcode))
623 .addReg(SrcReg, getKillRegState(IsKill))
624 .addFrameIndex(FI)
625 .addImm(0)
626 .addMemOperand(MMO);
627 }
628}
629
632 Register DstReg, int FI,
633 const TargetRegisterClass *RC,
634 const TargetRegisterInfo *TRI,
635 Register VReg) const {
637 MachineFrameInfo &MFI = MF->getFrameInfo();
638
639 unsigned Opcode;
640 bool IsScalableVector = true;
641 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
642 Opcode = TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
643 RISCV::LW : RISCV::LD;
644 IsScalableVector = false;
645 } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
646 Opcode = RISCV::PseudoRV32ZdinxLD;
647 IsScalableVector = false;
648 } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
649 Opcode = RISCV::FLH;
650 IsScalableVector = false;
651 } else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
652 Opcode = RISCV::FLW;
653 IsScalableVector = false;
654 } else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
655 Opcode = RISCV::FLD;
656 IsScalableVector = false;
657 } else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
658 Opcode = RISCV::VL1RE8_V;
659 } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
660 Opcode = RISCV::VL2RE8_V;
661 } else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
662 Opcode = RISCV::VL4RE8_V;
663 } else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
664 Opcode = RISCV::VL8RE8_V;
665 } else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
666 Opcode = RISCV::PseudoVRELOAD2_M1;
667 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
668 Opcode = RISCV::PseudoVRELOAD2_M2;
669 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
670 Opcode = RISCV::PseudoVRELOAD2_M4;
671 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
672 Opcode = RISCV::PseudoVRELOAD3_M1;
673 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
674 Opcode = RISCV::PseudoVRELOAD3_M2;
675 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
676 Opcode = RISCV::PseudoVRELOAD4_M1;
677 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
678 Opcode = RISCV::PseudoVRELOAD4_M2;
679 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
680 Opcode = RISCV::PseudoVRELOAD5_M1;
681 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
682 Opcode = RISCV::PseudoVRELOAD6_M1;
683 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
684 Opcode = RISCV::PseudoVRELOAD7_M1;
685 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
686 Opcode = RISCV::PseudoVRELOAD8_M1;
687 else
688 llvm_unreachable("Can't load this register from stack slot");
689
690 if (IsScalableVector) {
694
696 BuildMI(MBB, I, DebugLoc(), get(Opcode), DstReg)
697 .addFrameIndex(FI)
698 .addMemOperand(MMO);
699 } else {
702 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
703
704 BuildMI(MBB, I, DebugLoc(), get(Opcode), DstReg)
705 .addFrameIndex(FI)
706 .addImm(0)
707 .addMemOperand(MMO);
708 }
709}
710
713 MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS,
714 VirtRegMap *VRM) const {
715 const MachineFrameInfo &MFI = MF.getFrameInfo();
716
717 // The below optimizations narrow the load so they are only valid for little
718 // endian.
719 // TODO: Support big endian by adding an offset into the frame object?
720 if (MF.getDataLayout().isBigEndian())
721 return nullptr;
722
723 // Fold load from stack followed by sext.b/sext.h/sext.w/zext.b/zext.h/zext.w.
724 if (Ops.size() != 1 || Ops[0] != 1)
725 return nullptr;
726
727 unsigned LoadOpc;
728 switch (MI.getOpcode()) {
729 default:
730 if (RISCV::isSEXT_W(MI)) {
731 LoadOpc = RISCV::LW;
732 break;
733 }
734 if (RISCV::isZEXT_W(MI)) {
735 LoadOpc = RISCV::LWU;
736 break;
737 }
738 if (RISCV::isZEXT_B(MI)) {
739 LoadOpc = RISCV::LBU;
740 break;
741 }
742 return nullptr;
743 case RISCV::SEXT_H:
744 LoadOpc = RISCV::LH;
745 break;
746 case RISCV::SEXT_B:
747 LoadOpc = RISCV::LB;
748 break;
749 case RISCV::ZEXT_H_RV32:
750 case RISCV::ZEXT_H_RV64:
751 LoadOpc = RISCV::LHU;
752 break;
753 }
754
756 MachinePointerInfo::getFixedStack(MF, FrameIndex),
758 MFI.getObjectAlign(FrameIndex));
759
760 Register DstReg = MI.getOperand(0).getReg();
761 return BuildMI(*MI.getParent(), InsertPt, MI.getDebugLoc(), get(LoadOpc),
762 DstReg)
763 .addFrameIndex(FrameIndex)
764 .addImm(0)
765 .addMemOperand(MMO);
766}
767
770 const DebugLoc &DL, Register DstReg, uint64_t Val,
771 MachineInstr::MIFlag Flag, bool DstRenamable,
772 bool DstIsDead) const {
773 Register SrcReg = RISCV::X0;
774
775 // For RV32, allow a sign or unsigned 32 bit value.
776 if (!STI.is64Bit() && !isInt<32>(Val)) {
777 // If have a uimm32 it will still fit in a register so we can allow it.
778 if (!isUInt<32>(Val))
779 report_fatal_error("Should only materialize 32-bit constants for RV32");
780
781 // Sign extend for generateInstSeq.
782 Val = SignExtend64<32>(Val);
783 }
784
786 assert(!Seq.empty());
787
788 bool SrcRenamable = false;
789 unsigned Num = 0;
790
791 for (const RISCVMatInt::Inst &Inst : Seq) {
792 bool LastItem = ++Num == Seq.size();
793 unsigned DstRegState = getDeadRegState(DstIsDead && LastItem) |
794 getRenamableRegState(DstRenamable);
795 unsigned SrcRegState = getKillRegState(SrcReg != RISCV::X0) |
796 getRenamableRegState(SrcRenamable);
797 switch (Inst.getOpndKind()) {
798 case RISCVMatInt::Imm:
799 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
800 .addReg(DstReg, RegState::Define | DstRegState)
801 .addImm(Inst.getImm())
802 .setMIFlag(Flag);
803 break;
805 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
806 .addReg(DstReg, RegState::Define | DstRegState)
807 .addReg(SrcReg, SrcRegState)
808 .addReg(RISCV::X0)
809 .setMIFlag(Flag);
810 break;
812 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
813 .addReg(DstReg, RegState::Define | DstRegState)
814 .addReg(SrcReg, SrcRegState)
815 .addReg(SrcReg, SrcRegState)
816 .setMIFlag(Flag);
817 break;
819 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
820 .addReg(DstReg, RegState::Define | DstRegState)
821 .addReg(SrcReg, SrcRegState)
822 .addImm(Inst.getImm())
823 .setMIFlag(Flag);
824 break;
825 }
826
827 // Only the first instruction has X0 as its source.
828 SrcReg = DstReg;
829 SrcRenamable = DstRenamable;
830 }
831}
832
834 switch (Opc) {
835 default:
837 case RISCV::CV_BEQIMM:
838 return RISCVCC::COND_EQ;
839 case RISCV::CV_BNEIMM:
840 return RISCVCC::COND_NE;
841 case RISCV::BEQ:
842 return RISCVCC::COND_EQ;
843 case RISCV::BNE:
844 return RISCVCC::COND_NE;
845 case RISCV::BLT:
846 return RISCVCC::COND_LT;
847 case RISCV::BGE:
848 return RISCVCC::COND_GE;
849 case RISCV::BLTU:
850 return RISCVCC::COND_LTU;
851 case RISCV::BGEU:
852 return RISCVCC::COND_GEU;
853 }
854}
855
856// The contents of values added to Cond are not examined outside of
857// RISCVInstrInfo, giving us flexibility in what to push to it. For RISCV, we
858// push BranchOpcode, Reg1, Reg2.
861 // Block ends with fall-through condbranch.
862 assert(LastInst.getDesc().isConditionalBranch() &&
863 "Unknown conditional branch");
864 Target = LastInst.getOperand(2).getMBB();
865 unsigned CC = getCondFromBranchOpc(LastInst.getOpcode());
867 Cond.push_back(LastInst.getOperand(0));
868 Cond.push_back(LastInst.getOperand(1));
869}
870
872 switch (CC) {
873 default:
874 llvm_unreachable("Unknown condition code!");
875 case RISCVCC::COND_EQ:
876 return Imm ? RISCV::CV_BEQIMM : RISCV::BEQ;
877 case RISCVCC::COND_NE:
878 return Imm ? RISCV::CV_BNEIMM : RISCV::BNE;
879 case RISCVCC::COND_LT:
880 return RISCV::BLT;
881 case RISCVCC::COND_GE:
882 return RISCV::BGE;
884 return RISCV::BLTU;
886 return RISCV::BGEU;
887 }
888}
889
891 bool Imm) const {
892 return get(RISCVCC::getBrCond(CC, Imm));
893}
894
896 switch (CC) {
897 default:
898 llvm_unreachable("Unrecognized conditional branch");
899 case RISCVCC::COND_EQ:
900 return RISCVCC::COND_NE;
901 case RISCVCC::COND_NE:
902 return RISCVCC::COND_EQ;
903 case RISCVCC::COND_LT:
904 return RISCVCC::COND_GE;
905 case RISCVCC::COND_GE:
906 return RISCVCC::COND_LT;
908 return RISCVCC::COND_GEU;
910 return RISCVCC::COND_LTU;
911 }
912}
913
916 MachineBasicBlock *&FBB,
918 bool AllowModify) const {
919 TBB = FBB = nullptr;
920 Cond.clear();
921
922 // If the block has no terminators, it just falls into the block after it.
924 if (I == MBB.end() || !isUnpredicatedTerminator(*I))
925 return false;
926
927 // Count the number of terminators and find the first unconditional or
928 // indirect branch.
929 MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
930 int NumTerminators = 0;
931 for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
932 J++) {
933 NumTerminators++;
934 if (J->getDesc().isUnconditionalBranch() ||
935 J->getDesc().isIndirectBranch()) {
936 FirstUncondOrIndirectBr = J.getReverse();
937 }
938 }
939
940 // If AllowModify is true, we can erase any terminators after
941 // FirstUncondOrIndirectBR.
942 if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
943 while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
944 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
945 NumTerminators--;
946 }
947 I = FirstUncondOrIndirectBr;
948 }
949
950 // We can't handle blocks that end in an indirect branch.
951 if (I->getDesc().isIndirectBranch())
952 return true;
953
954 // We can't handle Generic branch opcodes from Global ISel.
955 if (I->isPreISelOpcode())
956 return true;
957
958 // We can't handle blocks with more than 2 terminators.
959 if (NumTerminators > 2)
960 return true;
961
962 // Handle a single unconditional branch.
963 if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
965 return false;
966 }
967
968 // Handle a single conditional branch.
969 if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
971 return false;
972 }
973
974 // Handle a conditional branch followed by an unconditional branch.
975 if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
976 I->getDesc().isUnconditionalBranch()) {
977 parseCondBranch(*std::prev(I), TBB, Cond);
978 FBB = getBranchDestBlock(*I);
979 return false;
980 }
981
982 // Otherwise, we can't handle this.
983 return true;
984}
985
987 int *BytesRemoved) const {
988 if (BytesRemoved)
989 *BytesRemoved = 0;
991 if (I == MBB.end())
992 return 0;
993
994 if (!I->getDesc().isUnconditionalBranch() &&
995 !I->getDesc().isConditionalBranch())
996 return 0;
997
998 // Remove the branch.
999 if (BytesRemoved)
1000 *BytesRemoved += getInstSizeInBytes(*I);
1001 I->eraseFromParent();
1002
1003 I = MBB.end();
1004
1005 if (I == MBB.begin())
1006 return 1;
1007 --I;
1008 if (!I->getDesc().isConditionalBranch())
1009 return 1;
1010
1011 // Remove the branch.
1012 if (BytesRemoved)
1013 *BytesRemoved += getInstSizeInBytes(*I);
1014 I->eraseFromParent();
1015 return 2;
1016}
1017
1018// Inserts a branch into the end of the specific MachineBasicBlock, returning
1019// the number of instructions inserted.
1022 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
1023 if (BytesAdded)
1024 *BytesAdded = 0;
1025
1026 // Shouldn't be a fall through.
1027 assert(TBB && "insertBranch must not be told to insert a fallthrough");
1028 assert((Cond.size() == 3 || Cond.size() == 0) &&
1029 "RISC-V branch conditions have two components!");
1030
1031 // Unconditional branch.
1032 if (Cond.empty()) {
1033 MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(TBB);
1034 if (BytesAdded)
1035 *BytesAdded += getInstSizeInBytes(MI);
1036 return 1;
1037 }
1038
1039 // Either a one or two-way conditional branch.
1040 auto CC = static_cast<RISCVCC::CondCode>(Cond[0].getImm());
1041 MachineInstr &CondMI = *BuildMI(&MBB, DL, getBrCond(CC, Cond[2].isImm()))
1042 .add(Cond[1])
1043 .add(Cond[2])
1044 .addMBB(TBB);
1045 if (BytesAdded)
1046 *BytesAdded += getInstSizeInBytes(CondMI);
1047
1048 // One-way conditional branch.
1049 if (!FBB)
1050 return 1;
1051
1052 // Two-way conditional branch.
1053 MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(FBB);
1054 if (BytesAdded)
1055 *BytesAdded += getInstSizeInBytes(MI);
1056 return 2;
1057}
1058
1060 MachineBasicBlock &DestBB,
1061 MachineBasicBlock &RestoreBB,
1062 const DebugLoc &DL, int64_t BrOffset,
1063 RegScavenger *RS) const {
1064 assert(RS && "RegScavenger required for long branching");
1065 assert(MBB.empty() &&
1066 "new block should be inserted for expanding unconditional branch");
1067 assert(MBB.pred_size() == 1);
1068 assert(RestoreBB.empty() &&
1069 "restore block should be inserted for restoring clobbered registers");
1070
1075
1076 if (!isInt<32>(BrOffset))
1078 "Branch offsets outside of the signed 32-bit range not supported");
1079
1080 // FIXME: A virtual register must be used initially, as the register
1081 // scavenger won't work with empty blocks (SIInstrInfo::insertIndirectBranch
1082 // uses the same workaround).
1083 Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRJALRRegClass);
1084 auto II = MBB.end();
1085 // We may also update the jump target to RestoreBB later.
1086 MachineInstr &MI = *BuildMI(MBB, II, DL, get(RISCV::PseudoJump))
1087 .addReg(ScratchReg, RegState::Define | RegState::Dead)
1088 .addMBB(&DestBB, RISCVII::MO_CALL);
1089
1091 Register TmpGPR =
1092 RS->scavengeRegisterBackwards(RISCV::GPRRegClass, MI.getIterator(),
1093 /*RestoreAfter=*/false, /*SpAdj=*/0,
1094 /*AllowSpill=*/false);
1095 if (TmpGPR != RISCV::NoRegister)
1096 RS->setRegUsed(TmpGPR);
1097 else {
1098 // The case when there is no scavenged register needs special handling.
1099
1100 // Pick s11 because it doesn't make a difference.
1101 TmpGPR = RISCV::X27;
1102
1103 int FrameIndex = RVFI->getBranchRelaxationScratchFrameIndex();
1104 if (FrameIndex == -1)
1105 report_fatal_error("underestimated function size");
1106
1107 storeRegToStackSlot(MBB, MI, TmpGPR, /*IsKill=*/true, FrameIndex,
1108 &RISCV::GPRRegClass, TRI, Register());
1109 TRI->eliminateFrameIndex(std::prev(MI.getIterator()),
1110 /*SpAdj=*/0, /*FIOperandNum=*/1);
1111
1112 MI.getOperand(1).setMBB(&RestoreBB);
1113
1114 loadRegFromStackSlot(RestoreBB, RestoreBB.end(), TmpGPR, FrameIndex,
1115 &RISCV::GPRRegClass, TRI, Register());
1116 TRI->eliminateFrameIndex(RestoreBB.back(),
1117 /*SpAdj=*/0, /*FIOperandNum=*/1);
1118 }
1119
1120 MRI.replaceRegWith(ScratchReg, TmpGPR);
1121 MRI.clearVirtRegs();
1122}
1123
1126 assert((Cond.size() == 3) && "Invalid branch condition!");
1127 auto CC = static_cast<RISCVCC::CondCode>(Cond[0].getImm());
1129 return false;
1130}
1131
1133 MachineBasicBlock *MBB = MI.getParent();
1135
1136 MachineBasicBlock *TBB, *FBB;
1138 if (analyzeBranch(*MBB, TBB, FBB, Cond, /*AllowModify=*/false))
1139 return false;
1140
1141 RISCVCC::CondCode CC = static_cast<RISCVCC::CondCode>(Cond[0].getImm());
1143
1145 return false;
1146
1147 // For two constants C0 and C1 from
1148 // ```
1149 // li Y, C0
1150 // li Z, C1
1151 // ```
1152 // 1. if C1 = C0 + 1
1153 // we can turn:
1154 // (a) blt Y, X -> bge X, Z
1155 // (b) bge Y, X -> blt X, Z
1156 //
1157 // 2. if C1 = C0 - 1
1158 // we can turn:
1159 // (a) blt X, Y -> bge Z, X
1160 // (b) bge X, Y -> blt Z, X
1161 //
1162 // To make sure this optimization is really beneficial, we only
1163 // optimize for cases where Y had only one use (i.e. only used by the branch).
1164
1165 // Right now we only care about LI (i.e. ADDI x0, imm)
1166 auto isLoadImm = [](const MachineInstr *MI, int64_t &Imm) -> bool {
1167 if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
1168 MI->getOperand(1).getReg() == RISCV::X0) {
1169 Imm = MI->getOperand(2).getImm();
1170 return true;
1171 }
1172 return false;
1173 };
1174 // Either a load from immediate instruction or X0.
1175 auto isFromLoadImm = [&](const MachineOperand &Op, int64_t &Imm) -> bool {
1176 if (!Op.isReg())
1177 return false;
1178 Register Reg = Op.getReg();
1179 return Reg.isVirtual() && isLoadImm(MRI.getVRegDef(Reg), Imm);
1180 };
1181
1182 MachineOperand &LHS = MI.getOperand(0);
1183 MachineOperand &RHS = MI.getOperand(1);
1184 // Try to find the register for constant Z; return
1185 // invalid register otherwise.
1186 auto searchConst = [&](int64_t C1) -> Register {
1188 auto DefC1 = std::find_if(++II, E, [&](const MachineInstr &I) -> bool {
1189 int64_t Imm;
1190 return isLoadImm(&I, Imm) && Imm == C1 &&
1191 I.getOperand(0).getReg().isVirtual();
1192 });
1193 if (DefC1 != E)
1194 return DefC1->getOperand(0).getReg();
1195
1196 return Register();
1197 };
1198
1199 bool Modify = false;
1200 int64_t C0;
1201 if (isFromLoadImm(LHS, C0) && MRI.hasOneUse(LHS.getReg())) {
1202 // Might be case 1.
1203 // Signed integer overflow is UB. (UINT64_MAX is bigger so we don't need
1204 // to worry about unsigned overflow here)
1205 if (C0 < INT64_MAX)
1206 if (Register RegZ = searchConst(C0 + 1)) {
1208 Cond[1] = MachineOperand::CreateReg(RHS.getReg(), /*isDef=*/false);
1209 Cond[2] = MachineOperand::CreateReg(RegZ, /*isDef=*/false);
1210 // We might extend the live range of Z, clear its kill flag to
1211 // account for this.
1212 MRI.clearKillFlags(RegZ);
1213 Modify = true;
1214 }
1215 } else if (isFromLoadImm(RHS, C0) && MRI.hasOneUse(RHS.getReg())) {
1216 // Might be case 2.
1217 // For unsigned cases, we don't want C1 to wrap back to UINT64_MAX
1218 // when C0 is zero.
1219 if ((CC == RISCVCC::COND_GE || CC == RISCVCC::COND_LT) || C0)
1220 if (Register RegZ = searchConst(C0 - 1)) {
1222 Cond[1] = MachineOperand::CreateReg(RegZ, /*isDef=*/false);
1223 Cond[2] = MachineOperand::CreateReg(LHS.getReg(), /*isDef=*/false);
1224 // We might extend the live range of Z, clear its kill flag to
1225 // account for this.
1226 MRI.clearKillFlags(RegZ);
1227 Modify = true;
1228 }
1229 }
1230
1231 if (!Modify)
1232 return false;
1233
1234 // Build the new branch and remove the old one.
1235 BuildMI(*MBB, MI, MI.getDebugLoc(),
1236 getBrCond(static_cast<RISCVCC::CondCode>(Cond[0].getImm())))
1237 .add(Cond[1])
1238 .add(Cond[2])
1239 .addMBB(TBB);
1240 MI.eraseFromParent();
1241
1242 return true;
1243}
1244
1247 assert(MI.getDesc().isBranch() && "Unexpected opcode!");
1248 // The branch target is always the last operand.
1249 int NumOp = MI.getNumExplicitOperands();
1250 return MI.getOperand(NumOp - 1).getMBB();
1251}
1252
1254 int64_t BrOffset) const {
1255 unsigned XLen = STI.getXLen();
1256 // Ideally we could determine the supported branch offset from the
1257 // RISCVII::FormMask, but this can't be used for Pseudo instructions like
1258 // PseudoBR.
1259 switch (BranchOp) {
1260 default:
1261 llvm_unreachable("Unexpected opcode!");
1262 case RISCV::BEQ:
1263 case RISCV::BNE:
1264 case RISCV::BLT:
1265 case RISCV::BGE:
1266 case RISCV::BLTU:
1267 case RISCV::BGEU:
1268 case RISCV::CV_BEQIMM:
1269 case RISCV::CV_BNEIMM:
1270 return isIntN(13, BrOffset);
1271 case RISCV::JAL:
1272 case RISCV::PseudoBR:
1273 return isIntN(21, BrOffset);
1274 case RISCV::PseudoJump:
1275 return isIntN(32, SignExtend64(BrOffset + 0x800, XLen));
1276 }
1277}
1278
1279// If the operation has a predicated pseudo instruction, return the pseudo
1280// instruction opcode. Otherwise, return RISCV::INSTRUCTION_LIST_END.
1281// TODO: Support more operations.
1282unsigned getPredicatedOpcode(unsigned Opcode) {
1283 switch (Opcode) {
1284 case RISCV::ADD: return RISCV::PseudoCCADD; break;
1285 case RISCV::SUB: return RISCV::PseudoCCSUB; break;
1286 case RISCV::SLL: return RISCV::PseudoCCSLL; break;
1287 case RISCV::SRL: return RISCV::PseudoCCSRL; break;
1288 case RISCV::SRA: return RISCV::PseudoCCSRA; break;
1289 case RISCV::AND: return RISCV::PseudoCCAND; break;
1290 case RISCV::OR: return RISCV::PseudoCCOR; break;
1291 case RISCV::XOR: return RISCV::PseudoCCXOR; break;
1292
1293 case RISCV::ADDI: return RISCV::PseudoCCADDI; break;
1294 case RISCV::SLLI: return RISCV::PseudoCCSLLI; break;
1295 case RISCV::SRLI: return RISCV::PseudoCCSRLI; break;
1296 case RISCV::SRAI: return RISCV::PseudoCCSRAI; break;
1297 case RISCV::ANDI: return RISCV::PseudoCCANDI; break;
1298 case RISCV::ORI: return RISCV::PseudoCCORI; break;
1299 case RISCV::XORI: return RISCV::PseudoCCXORI; break;
1300
1301 case RISCV::ADDW: return RISCV::PseudoCCADDW; break;
1302 case RISCV::SUBW: return RISCV::PseudoCCSUBW; break;
1303 case RISCV::SLLW: return RISCV::PseudoCCSLLW; break;
1304 case RISCV::SRLW: return RISCV::PseudoCCSRLW; break;
1305 case RISCV::SRAW: return RISCV::PseudoCCSRAW; break;
1306
1307 case RISCV::ADDIW: return RISCV::PseudoCCADDIW; break;
1308 case RISCV::SLLIW: return RISCV::PseudoCCSLLIW; break;
1309 case RISCV::SRLIW: return RISCV::PseudoCCSRLIW; break;
1310 case RISCV::SRAIW: return RISCV::PseudoCCSRAIW; break;
1311
1312 case RISCV::ANDN: return RISCV::PseudoCCANDN; break;
1313 case RISCV::ORN: return RISCV::PseudoCCORN; break;
1314 case RISCV::XNOR: return RISCV::PseudoCCXNOR; break;
1315 }
1316
1317 return RISCV::INSTRUCTION_LIST_END;
1318}
1319
1320/// Identify instructions that can be folded into a CCMOV instruction, and
1321/// return the defining instruction.
1323 const MachineRegisterInfo &MRI,
1324 const TargetInstrInfo *TII) {
1325 if (!Reg.isVirtual())
1326 return nullptr;
1327 if (!MRI.hasOneNonDBGUse(Reg))
1328 return nullptr;
1329 MachineInstr *MI = MRI.getVRegDef(Reg);
1330 if (!MI)
1331 return nullptr;
1332 // Check if MI can be predicated and folded into the CCMOV.
1333 if (getPredicatedOpcode(MI->getOpcode()) == RISCV::INSTRUCTION_LIST_END)
1334 return nullptr;
1335 // Don't predicate li idiom.
1336 if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
1337 MI->getOperand(1).getReg() == RISCV::X0)
1338 return nullptr;
1339 // Check if MI has any other defs or physreg uses.
1340 for (const MachineOperand &MO : llvm::drop_begin(MI->operands())) {
1341 // Reject frame index operands, PEI can't handle the predicated pseudos.
1342 if (MO.isFI() || MO.isCPI() || MO.isJTI())
1343 return nullptr;
1344 if (!MO.isReg())
1345 continue;
1346 // MI can't have any tied operands, that would conflict with predication.
1347 if (MO.isTied())
1348 return nullptr;
1349 if (MO.isDef())
1350 return nullptr;
1351 // Allow constant physregs.
1352 if (MO.getReg().isPhysical() && !MRI.isConstantPhysReg(MO.getReg()))
1353 return nullptr;
1354 }
1355 bool DontMoveAcrossStores = true;
1356 if (!MI->isSafeToMove(/* AliasAnalysis = */ nullptr, DontMoveAcrossStores))
1357 return nullptr;
1358 return MI;
1359}
1360
1363 unsigned &TrueOp, unsigned &FalseOp,
1364 bool &Optimizable) const {
1365 assert(MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1366 "Unknown select instruction");
1367 // CCMOV operands:
1368 // 0: Def.
1369 // 1: LHS of compare.
1370 // 2: RHS of compare.
1371 // 3: Condition code.
1372 // 4: False use.
1373 // 5: True use.
1374 TrueOp = 5;
1375 FalseOp = 4;
1376 Cond.push_back(MI.getOperand(1));
1377 Cond.push_back(MI.getOperand(2));
1378 Cond.push_back(MI.getOperand(3));
1379 // We can only fold when we support short forward branch opt.
1380 Optimizable = STI.hasShortForwardBranchOpt();
1381 return false;
1382}
1383
1387 bool PreferFalse) const {
1388 assert(MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1389 "Unknown select instruction");
1390 if (!STI.hasShortForwardBranchOpt())
1391 return nullptr;
1392
1393 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
1395 canFoldAsPredicatedOp(MI.getOperand(5).getReg(), MRI, this);
1396 bool Invert = !DefMI;
1397 if (!DefMI)
1398 DefMI = canFoldAsPredicatedOp(MI.getOperand(4).getReg(), MRI, this);
1399 if (!DefMI)
1400 return nullptr;
1401
1402 // Find new register class to use.
1403 MachineOperand FalseReg = MI.getOperand(Invert ? 5 : 4);
1404 Register DestReg = MI.getOperand(0).getReg();
1405 const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
1406 if (!MRI.constrainRegClass(DestReg, PreviousClass))
1407 return nullptr;
1408
1409 unsigned PredOpc = getPredicatedOpcode(DefMI->getOpcode());
1410 assert(PredOpc != RISCV::INSTRUCTION_LIST_END && "Unexpected opcode!");
1411
1412 // Create a new predicated version of DefMI.
1413 MachineInstrBuilder NewMI =
1414 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(PredOpc), DestReg);
1415
1416 // Copy the condition portion.
1417 NewMI.add(MI.getOperand(1));
1418 NewMI.add(MI.getOperand(2));
1419
1420 // Add condition code, inverting if necessary.
1421 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
1422 if (Invert)
1424 NewMI.addImm(CC);
1425
1426 // Copy the false register.
1427 NewMI.add(FalseReg);
1428
1429 // Copy all the DefMI operands.
1430 const MCInstrDesc &DefDesc = DefMI->getDesc();
1431 for (unsigned i = 1, e = DefDesc.getNumOperands(); i != e; ++i)
1432 NewMI.add(DefMI->getOperand(i));
1433
1434 // Update SeenMIs set: register newly created MI and erase removed DefMI.
1435 SeenMIs.insert(NewMI);
1436 SeenMIs.erase(DefMI);
1437
1438 // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
1439 // DefMI would be invalid when tranferred inside the loop. Checking for a
1440 // loop is expensive, but at least remove kill flags if they are in different
1441 // BBs.
1442 if (DefMI->getParent() != MI.getParent())
1443 NewMI->clearKillInfo();
1444
1445 // The caller will erase MI, but not DefMI.
1447 return NewMI;
1448}
1449
1451 if (MI.isMetaInstruction())
1452 return 0;
1453
1454 unsigned Opcode = MI.getOpcode();
1455
1456 if (Opcode == TargetOpcode::INLINEASM ||
1457 Opcode == TargetOpcode::INLINEASM_BR) {
1458 const MachineFunction &MF = *MI.getParent()->getParent();
1459 const auto &TM = static_cast<const RISCVTargetMachine &>(MF.getTarget());
1460 return getInlineAsmLength(MI.getOperand(0).getSymbolName(),
1461 *TM.getMCAsmInfo());
1462 }
1463
1464 if (!MI.memoperands_empty()) {
1465 MachineMemOperand *MMO = *(MI.memoperands_begin());
1466 const MachineFunction &MF = *MI.getParent()->getParent();
1467 const auto &ST = MF.getSubtarget<RISCVSubtarget>();
1468 if (ST.hasStdExtZihintntl() && MMO->isNonTemporal()) {
1469 if (ST.hasStdExtCOrZca() && ST.enableRVCHintInstrs()) {
1470 if (isCompressibleInst(MI, STI))
1471 return 4; // c.ntl.all + c.load/c.store
1472 return 6; // c.ntl.all + load/store
1473 }
1474 return 8; // ntl.all + load/store
1475 }
1476 }
1477
1478 if (Opcode == TargetOpcode::BUNDLE)
1479 return getInstBundleLength(MI);
1480
1481 if (MI.getParent() && MI.getParent()->getParent()) {
1482 if (isCompressibleInst(MI, STI))
1483 return 2;
1484 }
1485
1486 switch (Opcode) {
1487 case TargetOpcode::STACKMAP:
1488 // The upper bound for a stackmap intrinsic is the full length of its shadow
1490 case TargetOpcode::PATCHPOINT:
1491 // The size of the patchpoint intrinsic is the number of bytes requested
1493 case TargetOpcode::STATEPOINT: {
1494 // The size of the statepoint intrinsic is the number of bytes requested
1495 unsigned NumBytes = StatepointOpers(&MI).getNumPatchBytes();
1496 // No patch bytes means at most a PseudoCall is emitted
1497 return std::max(NumBytes, 8U);
1498 }
1499 default:
1500 return get(Opcode).getSize();
1501 }
1502}
1503
1504unsigned RISCVInstrInfo::getInstBundleLength(const MachineInstr &MI) const {
1505 unsigned Size = 0;
1507 MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
1508 while (++I != E && I->isInsideBundle()) {
1509 assert(!I->isBundle() && "No nested bundle!");
1511 }
1512 return Size;
1513}
1514
1516 const unsigned Opcode = MI.getOpcode();
1517 switch (Opcode) {
1518 default:
1519 break;
1520 case RISCV::FSGNJ_D:
1521 case RISCV::FSGNJ_S:
1522 case RISCV::FSGNJ_H:
1523 case RISCV::FSGNJ_D_INX:
1524 case RISCV::FSGNJ_D_IN32X:
1525 case RISCV::FSGNJ_S_INX:
1526 case RISCV::FSGNJ_H_INX:
1527 // The canonical floating-point move is fsgnj rd, rs, rs.
1528 return MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
1529 MI.getOperand(1).getReg() == MI.getOperand(2).getReg();
1530 case RISCV::ADDI:
1531 case RISCV::ORI:
1532 case RISCV::XORI:
1533 return (MI.getOperand(1).isReg() &&
1534 MI.getOperand(1).getReg() == RISCV::X0) ||
1535 (MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0);
1536 }
1537 return MI.isAsCheapAsAMove();
1538}
1539
1540std::optional<DestSourcePair>
1542 if (MI.isMoveReg())
1543 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1544 switch (MI.getOpcode()) {
1545 default:
1546 break;
1547 case RISCV::ADDI:
1548 // Operand 1 can be a frameindex but callers expect registers
1549 if (MI.getOperand(1).isReg() && MI.getOperand(2).isImm() &&
1550 MI.getOperand(2).getImm() == 0)
1551 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1552 break;
1553 case RISCV::FSGNJ_D:
1554 case RISCV::FSGNJ_S:
1555 case RISCV::FSGNJ_H:
1556 case RISCV::FSGNJ_D_INX:
1557 case RISCV::FSGNJ_D_IN32X:
1558 case RISCV::FSGNJ_S_INX:
1559 case RISCV::FSGNJ_H_INX:
1560 // The canonical floating-point move is fsgnj rd, rs, rs.
1561 if (MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
1562 MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
1563 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1564 break;
1565 }
1566 return std::nullopt;
1567}
1568
1570 if (ForceMachineCombinerStrategy.getNumOccurrences() == 0) {
1571 // The option is unused. Choose Local strategy only for in-order cores. When
1572 // scheduling model is unspecified, use MinInstrCount strategy as more
1573 // generic one.
1574 const auto &SchedModel = STI.getSchedModel();
1575 return (!SchedModel.hasInstrSchedModel() || SchedModel.isOutOfOrder())
1578 }
1579 // The strategy was forced by the option.
1581}
1582
1584 MachineInstr &Root, unsigned &Pattern,
1585 SmallVectorImpl<MachineInstr *> &InsInstrs) const {
1586 int16_t FrmOpIdx =
1587 RISCV::getNamedOperandIdx(Root.getOpcode(), RISCV::OpName::frm);
1588 if (FrmOpIdx < 0) {
1589 assert(all_of(InsInstrs,
1590 [](MachineInstr *MI) {
1591 return RISCV::getNamedOperandIdx(MI->getOpcode(),
1592 RISCV::OpName::frm) < 0;
1593 }) &&
1594 "New instructions require FRM whereas the old one does not have it");
1595 return;
1596 }
1597
1598 const MachineOperand &FRM = Root.getOperand(FrmOpIdx);
1599 MachineFunction &MF = *Root.getMF();
1600
1601 for (auto *NewMI : InsInstrs) {
1602 // We'd already added the FRM operand.
1603 if (static_cast<unsigned>(RISCV::getNamedOperandIdx(
1604 NewMI->getOpcode(), RISCV::OpName::frm)) != NewMI->getNumOperands())
1605 continue;
1606 MachineInstrBuilder MIB(MF, NewMI);
1607 MIB.add(FRM);
1608 if (FRM.getImm() == RISCVFPRndMode::DYN)
1609 MIB.addUse(RISCV::FRM, RegState::Implicit);
1610 }
1611}
1612
1613static bool isFADD(unsigned Opc) {
1614 switch (Opc) {
1615 default:
1616 return false;
1617 case RISCV::FADD_H:
1618 case RISCV::FADD_S:
1619 case RISCV::FADD_D:
1620 return true;
1621 }
1622}
1623
1624static bool isFSUB(unsigned Opc) {
1625 switch (Opc) {
1626 default:
1627 return false;
1628 case RISCV::FSUB_H:
1629 case RISCV::FSUB_S:
1630 case RISCV::FSUB_D:
1631 return true;
1632 }
1633}
1634
1635static bool isFMUL(unsigned Opc) {
1636 switch (Opc) {
1637 default:
1638 return false;
1639 case RISCV::FMUL_H:
1640 case RISCV::FMUL_S:
1641 case RISCV::FMUL_D:
1642 return true;
1643 }
1644}
1645
1646bool RISCVInstrInfo::isVectorAssociativeAndCommutative(const MachineInstr &Inst,
1647 bool Invert) const {
1648#define OPCODE_LMUL_CASE(OPC) \
1649 case RISCV::OPC##_M1: \
1650 case RISCV::OPC##_M2: \
1651 case RISCV::OPC##_M4: \
1652 case RISCV::OPC##_M8: \
1653 case RISCV::OPC##_MF2: \
1654 case RISCV::OPC##_MF4: \
1655 case RISCV::OPC##_MF8
1656
1657#define OPCODE_LMUL_MASK_CASE(OPC) \
1658 case RISCV::OPC##_M1_MASK: \
1659 case RISCV::OPC##_M2_MASK: \
1660 case RISCV::OPC##_M4_MASK: \
1661 case RISCV::OPC##_M8_MASK: \
1662 case RISCV::OPC##_MF2_MASK: \
1663 case RISCV::OPC##_MF4_MASK: \
1664 case RISCV::OPC##_MF8_MASK
1665
1666 unsigned Opcode = Inst.getOpcode();
1667 if (Invert) {
1668 if (auto InvOpcode = getInverseOpcode(Opcode))
1669 Opcode = *InvOpcode;
1670 else
1671 return false;
1672 }
1673
1674 // clang-format off
1675 switch (Opcode) {
1676 default:
1677 return false;
1678 OPCODE_LMUL_CASE(PseudoVADD_VV):
1679 OPCODE_LMUL_MASK_CASE(PseudoVADD_VV):
1680 OPCODE_LMUL_CASE(PseudoVMUL_VV):
1681 OPCODE_LMUL_MASK_CASE(PseudoVMUL_VV):
1682 return true;
1683 }
1684 // clang-format on
1685
1686#undef OPCODE_LMUL_MASK_CASE
1687#undef OPCODE_LMUL_CASE
1688}
1689
1690bool RISCVInstrInfo::areRVVInstsReassociable(const MachineInstr &Root,
1691 const MachineInstr &Prev) const {
1692 if (!areOpcodesEqualOrInverse(Root.getOpcode(), Prev.getOpcode()))
1693 return false;
1694
1695 assert(Root.getMF() == Prev.getMF());
1696 const MachineRegisterInfo *MRI = &Root.getMF()->getRegInfo();
1697 const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
1698
1699 // Make sure vtype operands are also the same.
1700 const MCInstrDesc &Desc = get(Root.getOpcode());
1701 const uint64_t TSFlags = Desc.TSFlags;
1702
1703 auto checkImmOperand = [&](unsigned OpIdx) {
1704 return Root.getOperand(OpIdx).getImm() == Prev.getOperand(OpIdx).getImm();
1705 };
1706
1707 auto checkRegOperand = [&](unsigned OpIdx) {
1708 return Root.getOperand(OpIdx).getReg() == Prev.getOperand(OpIdx).getReg();
1709 };
1710
1711 // PassThru
1712 // TODO: Potentially we can loosen the condition to consider Root to be
1713 // associable with Prev if Root has NoReg as passthru. In which case we
1714 // also need to loosen the condition on vector policies between these.
1715 if (!checkRegOperand(1))
1716 return false;
1717
1718 // SEW
1719 if (RISCVII::hasSEWOp(TSFlags) &&
1720 !checkImmOperand(RISCVII::getSEWOpNum(Desc)))
1721 return false;
1722
1723 // Mask
1724 if (RISCVII::usesMaskPolicy(TSFlags)) {
1725 const MachineBasicBlock *MBB = Root.getParent();
1728 Register MI1VReg;
1729
1730 bool SeenMI2 = false;
1731 for (auto End = MBB->rend(), It = It1; It != End; ++It) {
1732 if (It == It2) {
1733 SeenMI2 = true;
1734 if (!MI1VReg.isValid())
1735 // There is no V0 def between Root and Prev; they're sharing the
1736 // same V0.
1737 break;
1738 }
1739
1740 if (It->modifiesRegister(RISCV::V0, TRI)) {
1741 Register SrcReg = It->getOperand(1).getReg();
1742 // If it's not VReg it'll be more difficult to track its defs, so
1743 // bailing out here just to be safe.
1744 if (!SrcReg.isVirtual())
1745 return false;
1746
1747 if (!MI1VReg.isValid()) {
1748 // This is the V0 def for Root.
1749 MI1VReg = SrcReg;
1750 continue;
1751 }
1752
1753 // Some random mask updates.
1754 if (!SeenMI2)
1755 continue;
1756
1757 // This is the V0 def for Prev; check if it's the same as that of
1758 // Root.
1759 if (MI1VReg != SrcReg)
1760 return false;
1761 else
1762 break;
1763 }
1764 }
1765
1766 // If we haven't encountered Prev, it's likely that this function was
1767 // called in a wrong way (e.g. Root is before Prev).
1768 assert(SeenMI2 && "Prev is expected to appear before Root");
1769 }
1770
1771 // Tail / Mask policies
1772 if (RISCVII::hasVecPolicyOp(TSFlags) &&
1773 !checkImmOperand(RISCVII::getVecPolicyOpNum(Desc)))
1774 return false;
1775
1776 // VL
1777 if (RISCVII::hasVLOp(TSFlags)) {
1778 unsigned OpIdx = RISCVII::getVLOpNum(Desc);
1779 const MachineOperand &Op1 = Root.getOperand(OpIdx);
1780 const MachineOperand &Op2 = Prev.getOperand(OpIdx);
1781 if (Op1.getType() != Op2.getType())
1782 return false;
1783 switch (Op1.getType()) {
1785 if (Op1.getReg() != Op2.getReg())
1786 return false;
1787 break;
1789 if (Op1.getImm() != Op2.getImm())
1790 return false;
1791 break;
1792 default:
1793 llvm_unreachable("Unrecognized VL operand type");
1794 }
1795 }
1796
1797 // Rounding modes
1798 if (RISCVII::hasRoundModeOp(TSFlags) &&
1799 !checkImmOperand(RISCVII::getVLOpNum(Desc) - 1))
1800 return false;
1801
1802 return true;
1803}
1804
1805// Most of our RVV pseudos have passthru operand, so the real operands
1806// start from index = 2.
1807bool RISCVInstrInfo::hasReassociableVectorSibling(const MachineInstr &Inst,
1808 bool &Commuted) const {
1809 const MachineBasicBlock *MBB = Inst.getParent();
1812 "Expect the present of passthrough operand.");
1813 MachineInstr *MI1 = MRI.getUniqueVRegDef(Inst.getOperand(2).getReg());
1814 MachineInstr *MI2 = MRI.getUniqueVRegDef(Inst.getOperand(3).getReg());
1815
1816 // If only one operand has the same or inverse opcode and it's the second
1817 // source operand, the operands must be commuted.
1818 Commuted = !areRVVInstsReassociable(Inst, *MI1) &&
1819 areRVVInstsReassociable(Inst, *MI2);
1820 if (Commuted)
1821 std::swap(MI1, MI2);
1822
1823 return areRVVInstsReassociable(Inst, *MI1) &&
1824 (isVectorAssociativeAndCommutative(*MI1) ||
1825 isVectorAssociativeAndCommutative(*MI1, /* Invert */ true)) &&
1827 MRI.hasOneNonDBGUse(MI1->getOperand(0).getReg());
1828}
1829
1831 const MachineInstr &Inst, const MachineBasicBlock *MBB) const {
1832 if (!isVectorAssociativeAndCommutative(Inst) &&
1833 !isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
1835
1836 const MachineOperand &Op1 = Inst.getOperand(2);
1837 const MachineOperand &Op2 = Inst.getOperand(3);
1839
1840 // We need virtual register definitions for the operands that we will
1841 // reassociate.
1842 MachineInstr *MI1 = nullptr;
1843 MachineInstr *MI2 = nullptr;
1844 if (Op1.isReg() && Op1.getReg().isVirtual())
1845 MI1 = MRI.getUniqueVRegDef(Op1.getReg());
1846 if (Op2.isReg() && Op2.getReg().isVirtual())
1847 MI2 = MRI.getUniqueVRegDef(Op2.getReg());
1848
1849 // And at least one operand must be defined in MBB.
1850 return MI1 && MI2 && (MI1->getParent() == MBB || MI2->getParent() == MBB);
1851}
1852
1854 const MachineInstr &Root, unsigned Pattern,
1855 std::array<unsigned, 5> &OperandIndices) const {
1857 if (RISCV::getRVVMCOpcode(Root.getOpcode())) {
1858 // Skip the passthrough operand, so increment all indices by one.
1859 for (unsigned I = 0; I < 5; ++I)
1860 ++OperandIndices[I];
1861 }
1862}
1863
1865 bool &Commuted) const {
1866 if (isVectorAssociativeAndCommutative(Inst) ||
1867 isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
1868 return hasReassociableVectorSibling(Inst, Commuted);
1869
1870 if (!TargetInstrInfo::hasReassociableSibling(Inst, Commuted))
1871 return false;
1872
1873 const MachineRegisterInfo &MRI = Inst.getMF()->getRegInfo();
1874 unsigned OperandIdx = Commuted ? 2 : 1;
1875 const MachineInstr &Sibling =
1876 *MRI.getVRegDef(Inst.getOperand(OperandIdx).getReg());
1877
1878 int16_t InstFrmOpIdx =
1879 RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::frm);
1880 int16_t SiblingFrmOpIdx =
1881 RISCV::getNamedOperandIdx(Sibling.getOpcode(), RISCV::OpName::frm);
1882
1883 return (InstFrmOpIdx < 0 && SiblingFrmOpIdx < 0) ||
1884 RISCV::hasEqualFRM(Inst, Sibling);
1885}
1886
1888 bool Invert) const {
1889 if (isVectorAssociativeAndCommutative(Inst, Invert))
1890 return true;
1891
1892 unsigned Opc = Inst.getOpcode();
1893 if (Invert) {
1894 auto InverseOpcode = getInverseOpcode(Opc);
1895 if (!InverseOpcode)
1896 return false;
1897 Opc = *InverseOpcode;
1898 }
1899
1900 if (isFADD(Opc) || isFMUL(Opc))
1903
1904 switch (Opc) {
1905 default:
1906 return false;
1907 case RISCV::ADD:
1908 case RISCV::ADDW:
1909 case RISCV::AND:
1910 case RISCV::OR:
1911 case RISCV::XOR:
1912 // From RISC-V ISA spec, if both the high and low bits of the same product
1913 // are required, then the recommended code sequence is:
1914 //
1915 // MULH[[S]U] rdh, rs1, rs2
1916 // MUL rdl, rs1, rs2
1917 // (source register specifiers must be in same order and rdh cannot be the
1918 // same as rs1 or rs2)
1919 //
1920 // Microarchitectures can then fuse these into a single multiply operation
1921 // instead of performing two separate multiplies.
1922 // MachineCombiner may reassociate MUL operands and lose the fusion
1923 // opportunity.
1924 case RISCV::MUL:
1925 case RISCV::MULW:
1926 case RISCV::MIN:
1927 case RISCV::MINU:
1928 case RISCV::MAX:
1929 case RISCV::MAXU:
1930 case RISCV::FMIN_H:
1931 case RISCV::FMIN_S:
1932 case RISCV::FMIN_D:
1933 case RISCV::FMAX_H:
1934 case RISCV::FMAX_S:
1935 case RISCV::FMAX_D:
1936 return true;
1937 }
1938
1939 return false;
1940}
1941
1942std::optional<unsigned>
1943RISCVInstrInfo::getInverseOpcode(unsigned Opcode) const {
1944#define RVV_OPC_LMUL_CASE(OPC, INV) \
1945 case RISCV::OPC##_M1: \
1946 return RISCV::INV##_M1; \
1947 case RISCV::OPC##_M2: \
1948 return RISCV::INV##_M2; \
1949 case RISCV::OPC##_M4: \
1950 return RISCV::INV##_M4; \
1951 case RISCV::OPC##_M8: \
1952 return RISCV::INV##_M8; \
1953 case RISCV::OPC##_MF2: \
1954 return RISCV::INV##_MF2; \
1955 case RISCV::OPC##_MF4: \
1956 return RISCV::INV##_MF4; \
1957 case RISCV::OPC##_MF8: \
1958 return RISCV::INV##_MF8
1959
1960#define RVV_OPC_LMUL_MASK_CASE(OPC, INV) \
1961 case RISCV::OPC##_M1_MASK: \
1962 return RISCV::INV##_M1_MASK; \
1963 case RISCV::OPC##_M2_MASK: \
1964 return RISCV::INV##_M2_MASK; \
1965 case RISCV::OPC##_M4_MASK: \
1966 return RISCV::INV##_M4_MASK; \
1967 case RISCV::OPC##_M8_MASK: \
1968 return RISCV::INV##_M8_MASK; \
1969 case RISCV::OPC##_MF2_MASK: \
1970 return RISCV::INV##_MF2_MASK; \
1971 case RISCV::OPC##_MF4_MASK: \
1972 return RISCV::INV##_MF4_MASK; \
1973 case RISCV::OPC##_MF8_MASK: \
1974 return RISCV::INV##_MF8_MASK
1975
1976 switch (Opcode) {
1977 default:
1978 return std::nullopt;
1979 case RISCV::FADD_H:
1980 return RISCV::FSUB_H;
1981 case RISCV::FADD_S:
1982 return RISCV::FSUB_S;
1983 case RISCV::FADD_D:
1984 return RISCV::FSUB_D;
1985 case RISCV::FSUB_H:
1986 return RISCV::FADD_H;
1987 case RISCV::FSUB_S:
1988 return RISCV::FADD_S;
1989 case RISCV::FSUB_D:
1990 return RISCV::FADD_D;
1991 case RISCV::ADD:
1992 return RISCV::SUB;
1993 case RISCV::SUB:
1994 return RISCV::ADD;
1995 case RISCV::ADDW:
1996 return RISCV::SUBW;
1997 case RISCV::SUBW:
1998 return RISCV::ADDW;
1999 // clang-format off
2000 RVV_OPC_LMUL_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2001 RVV_OPC_LMUL_MASK_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2002 RVV_OPC_LMUL_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2003 RVV_OPC_LMUL_MASK_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2004 // clang-format on
2005 }
2006
2007#undef RVV_OPC_LMUL_MASK_CASE
2008#undef RVV_OPC_LMUL_CASE
2009}
2010
2012 const MachineOperand &MO,
2013 bool DoRegPressureReduce) {
2014 if (!MO.isReg() || !MO.getReg().isVirtual())
2015 return false;
2016 const MachineRegisterInfo &MRI = Root.getMF()->getRegInfo();
2017 MachineInstr *MI = MRI.getVRegDef(MO.getReg());
2018 if (!MI || !isFMUL(MI->getOpcode()))
2019 return false;
2020
2023 return false;
2024
2025 // Try combining even if fmul has more than one use as it eliminates
2026 // dependency between fadd(fsub) and fmul. However, it can extend liveranges
2027 // for fmul operands, so reject the transformation in register pressure
2028 // reduction mode.
2029 if (DoRegPressureReduce && !MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2030 return false;
2031
2032 // Do not combine instructions from different basic blocks.
2033 if (Root.getParent() != MI->getParent())
2034 return false;
2035 return RISCV::hasEqualFRM(Root, *MI);
2036}
2037
2039 SmallVectorImpl<unsigned> &Patterns,
2040 bool DoRegPressureReduce) {
2041 unsigned Opc = Root.getOpcode();
2042 bool IsFAdd = isFADD(Opc);
2043 if (!IsFAdd && !isFSUB(Opc))
2044 return false;
2045 bool Added = false;
2046 if (canCombineFPFusedMultiply(Root, Root.getOperand(1),
2047 DoRegPressureReduce)) {
2050 Added = true;
2051 }
2052 if (canCombineFPFusedMultiply(Root, Root.getOperand(2),
2053 DoRegPressureReduce)) {
2056 Added = true;
2057 }
2058 return Added;
2059}
2060
2061static bool getFPPatterns(MachineInstr &Root,
2062 SmallVectorImpl<unsigned> &Patterns,
2063 bool DoRegPressureReduce) {
2064 return getFPFusedMultiplyPatterns(Root, Patterns, DoRegPressureReduce);
2065}
2066
2067/// Utility routine that checks if \param MO is defined by an
2068/// \param CombineOpc instruction in the basic block \param MBB
2070 const MachineOperand &MO,
2071 unsigned CombineOpc) {
2073 const MachineInstr *MI = nullptr;
2074
2075 if (MO.isReg() && MO.getReg().isVirtual())
2076 MI = MRI.getUniqueVRegDef(MO.getReg());
2077 // And it needs to be in the trace (otherwise, it won't have a depth).
2078 if (!MI || MI->getParent() != &MBB || MI->getOpcode() != CombineOpc)
2079 return nullptr;
2080 // Must only used by the user we combine with.
2081 if (!MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2082 return nullptr;
2083
2084 return MI;
2085}
2086
2087/// Utility routine that checks if \param MO is defined by a SLLI in \param
2088/// MBB that can be combined by splitting across 2 SHXADD instructions. The
2089/// first SHXADD shift amount is given by \param OuterShiftAmt.
2091 const MachineOperand &MO,
2092 unsigned OuterShiftAmt) {
2093 const MachineInstr *ShiftMI = canCombine(MBB, MO, RISCV::SLLI);
2094 if (!ShiftMI)
2095 return false;
2096
2097 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2098 if (InnerShiftAmt < OuterShiftAmt || (InnerShiftAmt - OuterShiftAmt) > 3)
2099 return false;
2100
2101 return true;
2102}
2103
2104// Returns the shift amount from a SHXADD instruction. Returns 0 if the
2105// instruction is not a SHXADD.
2106static unsigned getSHXADDShiftAmount(unsigned Opc) {
2107 switch (Opc) {
2108 default:
2109 return 0;
2110 case RISCV::SH1ADD:
2111 return 1;
2112 case RISCV::SH2ADD:
2113 return 2;
2114 case RISCV::SH3ADD:
2115 return 3;
2116 }
2117}
2118
2119// Look for opportunities to combine (sh3add Z, (add X, (slli Y, 5))) into
2120// (sh3add (sh2add Y, Z), X).
2121static bool getSHXADDPatterns(const MachineInstr &Root,
2122 SmallVectorImpl<unsigned> &Patterns) {
2123 unsigned ShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2124 if (!ShiftAmt)
2125 return false;
2126
2127 const MachineBasicBlock &MBB = *Root.getParent();
2128
2129 const MachineInstr *AddMI = canCombine(MBB, Root.getOperand(2), RISCV::ADD);
2130 if (!AddMI)
2131 return false;
2132
2133 bool Found = false;
2134 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(1), ShiftAmt)) {
2136 Found = true;
2137 }
2138 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(2), ShiftAmt)) {
2140 Found = true;
2141 }
2142
2143 return Found;
2144}
2145
2147 switch (Pattern) {
2153 default:
2155 }
2156}
2157
2159 MachineInstr &Root, SmallVectorImpl<unsigned> &Patterns,
2160 bool DoRegPressureReduce) const {
2161
2162 if (getFPPatterns(Root, Patterns, DoRegPressureReduce))
2163 return true;
2164
2165 if (getSHXADDPatterns(Root, Patterns))
2166 return true;
2167
2168 return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
2169 DoRegPressureReduce);
2170}
2171
2172static unsigned getFPFusedMultiplyOpcode(unsigned RootOpc, unsigned Pattern) {
2173 switch (RootOpc) {
2174 default:
2175 llvm_unreachable("Unexpected opcode");
2176 case RISCV::FADD_H:
2177 return RISCV::FMADD_H;
2178 case RISCV::FADD_S:
2179 return RISCV::FMADD_S;
2180 case RISCV::FADD_D:
2181 return RISCV::FMADD_D;
2182 case RISCV::FSUB_H:
2183 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_H
2184 : RISCV::FNMSUB_H;
2185 case RISCV::FSUB_S:
2186 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_S
2187 : RISCV::FNMSUB_S;
2188 case RISCV::FSUB_D:
2189 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_D
2190 : RISCV::FNMSUB_D;
2191 }
2192}
2193
2194static unsigned getAddendOperandIdx(unsigned Pattern) {
2195 switch (Pattern) {
2196 default:
2197 llvm_unreachable("Unexpected pattern");
2200 return 2;
2203 return 1;
2204 }
2205}
2206
2208 unsigned Pattern,
2211 MachineFunction *MF = Root.getMF();
2214
2215 MachineOperand &Mul1 = Prev.getOperand(1);
2216 MachineOperand &Mul2 = Prev.getOperand(2);
2217 MachineOperand &Dst = Root.getOperand(0);
2219
2220 Register DstReg = Dst.getReg();
2221 unsigned FusedOpc = getFPFusedMultiplyOpcode(Root.getOpcode(), Pattern);
2222 uint32_t IntersectedFlags = Root.getFlags() & Prev.getFlags();
2223 DebugLoc MergedLoc =
2225
2226 bool Mul1IsKill = Mul1.isKill();
2227 bool Mul2IsKill = Mul2.isKill();
2228 bool AddendIsKill = Addend.isKill();
2229
2230 // We need to clear kill flags since we may be extending the live range past
2231 // a kill. If the mul had kill flags, we can preserve those since we know
2232 // where the previous range stopped.
2233 MRI.clearKillFlags(Mul1.getReg());
2234 MRI.clearKillFlags(Mul2.getReg());
2235
2237 BuildMI(*MF, MergedLoc, TII->get(FusedOpc), DstReg)
2238 .addReg(Mul1.getReg(), getKillRegState(Mul1IsKill))
2239 .addReg(Mul2.getReg(), getKillRegState(Mul2IsKill))
2240 .addReg(Addend.getReg(), getKillRegState(AddendIsKill))
2241 .setMIFlags(IntersectedFlags);
2242
2243 InsInstrs.push_back(MIB);
2244 if (MRI.hasOneNonDBGUse(Prev.getOperand(0).getReg()))
2245 DelInstrs.push_back(&Prev);
2246 DelInstrs.push_back(&Root);
2247}
2248
2249// Combine patterns like (sh3add Z, (add X, (slli Y, 5))) to
2250// (sh3add (sh2add Y, Z), X) if the shift amount can be split across two
2251// shXadd instructions. The outer shXadd keeps its original opcode.
2252static void
2253genShXAddAddShift(MachineInstr &Root, unsigned AddOpIdx,
2256 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) {
2257 MachineFunction *MF = Root.getMF();
2260
2261 unsigned OuterShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2262 assert(OuterShiftAmt != 0 && "Unexpected opcode");
2263
2264 MachineInstr *AddMI = MRI.getUniqueVRegDef(Root.getOperand(2).getReg());
2265 MachineInstr *ShiftMI =
2266 MRI.getUniqueVRegDef(AddMI->getOperand(AddOpIdx).getReg());
2267
2268 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2269 assert(InnerShiftAmt >= OuterShiftAmt && "Unexpected shift amount");
2270
2271 unsigned InnerOpc;
2272 switch (InnerShiftAmt - OuterShiftAmt) {
2273 default:
2274 llvm_unreachable("Unexpected shift amount");
2275 case 0:
2276 InnerOpc = RISCV::ADD;
2277 break;
2278 case 1:
2279 InnerOpc = RISCV::SH1ADD;
2280 break;
2281 case 2:
2282 InnerOpc = RISCV::SH2ADD;
2283 break;
2284 case 3:
2285 InnerOpc = RISCV::SH3ADD;
2286 break;
2287 }
2288
2289 const MachineOperand &X = AddMI->getOperand(3 - AddOpIdx);
2290 const MachineOperand &Y = ShiftMI->getOperand(1);
2291 const MachineOperand &Z = Root.getOperand(1);
2292
2293 Register NewVR = MRI.createVirtualRegister(&RISCV::GPRRegClass);
2294
2295 auto MIB1 = BuildMI(*MF, MIMetadata(Root), TII->get(InnerOpc), NewVR)
2296 .addReg(Y.getReg(), getKillRegState(Y.isKill()))
2297 .addReg(Z.getReg(), getKillRegState(Z.isKill()));
2298 auto MIB2 = BuildMI(*MF, MIMetadata(Root), TII->get(Root.getOpcode()),
2299 Root.getOperand(0).getReg())
2300 .addReg(NewVR, RegState::Kill)
2301 .addReg(X.getReg(), getKillRegState(X.isKill()));
2302
2303 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));
2304 InsInstrs.push_back(MIB1);
2305 InsInstrs.push_back(MIB2);
2306 DelInstrs.push_back(ShiftMI);
2307 DelInstrs.push_back(AddMI);
2308 DelInstrs.push_back(&Root);
2309}
2310
2312 MachineInstr &Root, unsigned Pattern,
2315 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const {
2317 switch (Pattern) {
2318 default:
2320 DelInstrs, InstrIdxForVirtReg);
2321 return;
2324 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(1).getReg());
2325 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2326 return;
2327 }
2330 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(2).getReg());
2331 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2332 return;
2333 }
2335 genShXAddAddShift(Root, 1, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2336 return;
2338 genShXAddAddShift(Root, 2, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2339 return;
2340 }
2341}
2342
2344 StringRef &ErrInfo) const {
2345 MCInstrDesc const &Desc = MI.getDesc();
2346
2347 for (const auto &[Index, Operand] : enumerate(Desc.operands())) {
2348 unsigned OpType = Operand.OperandType;
2349 if (OpType >= RISCVOp::OPERAND_FIRST_RISCV_IMM &&
2351 const MachineOperand &MO = MI.getOperand(Index);
2352 if (MO.isImm()) {
2353 int64_t Imm = MO.getImm();
2354 bool Ok;
2355 switch (OpType) {
2356 default:
2357 llvm_unreachable("Unexpected operand type");
2358
2359 // clang-format off
2360#define CASE_OPERAND_UIMM(NUM) \
2361 case RISCVOp::OPERAND_UIMM##NUM: \
2362 Ok = isUInt<NUM>(Imm); \
2363 break;
2374 // clang-format on
2376 Ok = isShiftedUInt<1, 1>(Imm);
2377 break;
2379 Ok = isShiftedUInt<5, 2>(Imm);
2380 break;
2382 Ok = isShiftedUInt<6, 2>(Imm);
2383 break;
2385 Ok = isShiftedUInt<5, 3>(Imm);
2386 break;
2388 Ok = isUInt<8>(Imm) && Imm >= 32;
2389 break;
2391 Ok = isShiftedUInt<6, 3>(Imm);
2392 break;
2394 Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
2395 break;
2397 Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0);
2398 break;
2400 Ok = Imm == 0;
2401 break;
2403 Ok = isInt<5>(Imm);
2404 break;
2406 Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16;
2407 break;
2409 Ok = isInt<6>(Imm);
2410 break;
2412 Ok = Imm != 0 && isInt<6>(Imm);
2413 break;
2415 Ok = isUInt<10>(Imm);
2416 break;
2418 Ok = isUInt<11>(Imm);
2419 break;
2421 Ok = isInt<12>(Imm);
2422 break;
2424 Ok = isShiftedInt<7, 5>(Imm);
2425 break;
2427 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
2428 break;
2430 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
2431 Ok = Ok && Imm != 0;
2432 break;
2434 Ok = (isUInt<5>(Imm) && Imm != 0) ||
2435 (Imm >= 0xfffe0 && Imm <= 0xfffff);
2436 break;
2438 Ok = Imm >= 0 && Imm <= 10;
2439 break;
2441 Ok = Imm >= 0 && Imm <= 7;
2442 break;
2444 Ok = Imm >= 1 && Imm <= 10;
2445 break;
2447 Ok = Imm >= 2 && Imm <= 14;
2448 break;
2450 Ok = (Imm & 0xf) == 0;
2451 break;
2452 }
2453 if (!Ok) {
2454 ErrInfo = "Invalid immediate";
2455 return false;
2456 }
2457 }
2458 }
2459 }
2460
2461 const uint64_t TSFlags = Desc.TSFlags;
2462 if (RISCVII::hasVLOp(TSFlags)) {
2463 const MachineOperand &Op = MI.getOperand(RISCVII::getVLOpNum(Desc));
2464 if (!Op.isImm() && !Op.isReg()) {
2465 ErrInfo = "Invalid operand type for VL operand";
2466 return false;
2467 }
2468 if (Op.isReg() && Op.getReg() != RISCV::NoRegister) {
2469 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
2470 auto *RC = MRI.getRegClass(Op.getReg());
2471 if (!RISCV::GPRRegClass.hasSubClassEq(RC)) {
2472 ErrInfo = "Invalid register class for VL operand";
2473 return false;
2474 }
2475 }
2476 if (!RISCVII::hasSEWOp(TSFlags)) {
2477 ErrInfo = "VL operand w/o SEW operand?";
2478 return false;
2479 }
2480 }
2481 if (RISCVII::hasSEWOp(TSFlags)) {
2482 unsigned OpIdx = RISCVII::getSEWOpNum(Desc);
2483 if (!MI.getOperand(OpIdx).isImm()) {
2484 ErrInfo = "SEW value expected to be an immediate";
2485 return false;
2486 }
2487 uint64_t Log2SEW = MI.getOperand(OpIdx).getImm();
2488 if (Log2SEW > 31) {
2489 ErrInfo = "Unexpected SEW value";
2490 return false;
2491 }
2492 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
2493 if (!RISCVVType::isValidSEW(SEW)) {
2494 ErrInfo = "Unexpected SEW value";
2495 return false;
2496 }
2497 }
2498 if (RISCVII::hasVecPolicyOp(TSFlags)) {
2499 unsigned OpIdx = RISCVII::getVecPolicyOpNum(Desc);
2500 if (!MI.getOperand(OpIdx).isImm()) {
2501 ErrInfo = "Policy operand expected to be an immediate";
2502 return false;
2503 }
2504 uint64_t Policy = MI.getOperand(OpIdx).getImm();
2506 ErrInfo = "Invalid Policy Value";
2507 return false;
2508 }
2509 if (!RISCVII::hasVLOp(TSFlags)) {
2510 ErrInfo = "policy operand w/o VL operand?";
2511 return false;
2512 }
2513
2514 // VecPolicy operands can only exist on instructions with passthru/merge
2515 // arguments. Note that not all arguments with passthru have vec policy
2516 // operands- some instructions have implicit policies.
2517 unsigned UseOpIdx;
2518 if (!MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
2519 ErrInfo = "policy operand w/o tied operand?";
2520 return false;
2521 }
2522 }
2523
2524 return true;
2525}
2526
2528 const MachineInstr &AddrI,
2529 ExtAddrMode &AM) const {
2530 switch (MemI.getOpcode()) {
2531 default:
2532 return false;
2533 case RISCV::LB:
2534 case RISCV::LBU:
2535 case RISCV::LH:
2536 case RISCV::LHU:
2537 case RISCV::LW:
2538 case RISCV::LWU:
2539 case RISCV::LD:
2540 case RISCV::FLH:
2541 case RISCV::FLW:
2542 case RISCV::FLD:
2543 case RISCV::SB:
2544 case RISCV::SH:
2545 case RISCV::SW:
2546 case RISCV::SD:
2547 case RISCV::FSH:
2548 case RISCV::FSW:
2549 case RISCV::FSD:
2550 break;
2551 }
2552
2553 if (MemI.getOperand(0).getReg() == Reg)
2554 return false;
2555
2556 if (AddrI.getOpcode() != RISCV::ADDI || !AddrI.getOperand(1).isReg() ||
2557 !AddrI.getOperand(2).isImm())
2558 return false;
2559
2560 int64_t OldOffset = MemI.getOperand(2).getImm();
2561 int64_t Disp = AddrI.getOperand(2).getImm();
2562 int64_t NewOffset = OldOffset + Disp;
2563 if (!STI.is64Bit())
2564 NewOffset = SignExtend64<32>(NewOffset);
2565
2566 if (!isInt<12>(NewOffset))
2567 return false;
2568
2569 AM.BaseReg = AddrI.getOperand(1).getReg();
2570 AM.ScaledReg = 0;
2571 AM.Scale = 0;
2572 AM.Displacement = NewOffset;
2574 return true;
2575}
2576
2578 const ExtAddrMode &AM) const {
2579
2580 const DebugLoc &DL = MemI.getDebugLoc();
2581 MachineBasicBlock &MBB = *MemI.getParent();
2582
2583 assert(AM.ScaledReg == 0 && AM.Scale == 0 &&
2584 "Addressing mode not supported for folding");
2585
2586 return BuildMI(MBB, MemI, DL, get(MemI.getOpcode()))
2587 .addReg(MemI.getOperand(0).getReg(),
2588 MemI.mayLoad() ? RegState::Define : 0)
2589 .addReg(AM.BaseReg)
2590 .addImm(AM.Displacement)
2591 .setMemRefs(MemI.memoperands())
2592 .setMIFlags(MemI.getFlags());
2593}
2594
2597 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
2598 const TargetRegisterInfo *TRI) const {
2599 if (!LdSt.mayLoadOrStore())
2600 return false;
2601
2602 // Conservatively, only handle scalar loads/stores for now.
2603 switch (LdSt.getOpcode()) {
2604 case RISCV::LB:
2605 case RISCV::LBU:
2606 case RISCV::SB:
2607 case RISCV::LH:
2608 case RISCV::LHU:
2609 case RISCV::FLH:
2610 case RISCV::SH:
2611 case RISCV::FSH:
2612 case RISCV::LW:
2613 case RISCV::LWU:
2614 case RISCV::FLW:
2615 case RISCV::SW:
2616 case RISCV::FSW:
2617 case RISCV::LD:
2618 case RISCV::FLD:
2619 case RISCV::SD:
2620 case RISCV::FSD:
2621 break;
2622 default:
2623 return false;
2624 }
2625 const MachineOperand *BaseOp;
2626 OffsetIsScalable = false;
2627 if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
2628 return false;
2629 BaseOps.push_back(BaseOp);
2630 return true;
2631}
2632
2633// TODO: This was copied from SIInstrInfo. Could it be lifted to a common
2634// helper?
2637 const MachineInstr &MI2,
2639 // Only examine the first "base" operand of each instruction, on the
2640 // assumption that it represents the real base address of the memory access.
2641 // Other operands are typically offsets or indices from this base address.
2642 if (BaseOps1.front()->isIdenticalTo(*BaseOps2.front()))
2643 return true;
2644
2645 if (!MI1.hasOneMemOperand() || !MI2.hasOneMemOperand())
2646 return false;
2647
2648 auto MO1 = *MI1.memoperands_begin();
2649 auto MO2 = *MI2.memoperands_begin();
2650 if (MO1->getAddrSpace() != MO2->getAddrSpace())
2651 return false;
2652
2653 auto Base1 = MO1->getValue();
2654 auto Base2 = MO2->getValue();
2655 if (!Base1 || !Base2)
2656 return false;
2657 Base1 = getUnderlyingObject(Base1);
2658 Base2 = getUnderlyingObject(Base2);
2659
2660 if (isa<UndefValue>(Base1) || isa<UndefValue>(Base2))
2661 return false;
2662
2663 return Base1 == Base2;
2664}
2665
2667 ArrayRef<const MachineOperand *> BaseOps1, int64_t Offset1,
2668 bool OffsetIsScalable1, ArrayRef<const MachineOperand *> BaseOps2,
2669 int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize,
2670 unsigned NumBytes) const {
2671 // If the mem ops (to be clustered) do not have the same base ptr, then they
2672 // should not be clustered
2673 if (!BaseOps1.empty() && !BaseOps2.empty()) {
2674 const MachineInstr &FirstLdSt = *BaseOps1.front()->getParent();
2675 const MachineInstr &SecondLdSt = *BaseOps2.front()->getParent();
2676 if (!memOpsHaveSameBasePtr(FirstLdSt, BaseOps1, SecondLdSt, BaseOps2))
2677 return false;
2678 } else if (!BaseOps1.empty() || !BaseOps2.empty()) {
2679 // If only one base op is empty, they do not have the same base ptr
2680 return false;
2681 }
2682
2683 unsigned CacheLineSize =
2684 BaseOps1.front()->getParent()->getMF()->getSubtarget().getCacheLineSize();
2685 // Assume a cache line size of 64 bytes if no size is set in RISCVSubtarget.
2687 // Cluster if the memory operations are on the same or a neighbouring cache
2688 // line, but limit the maximum ClusterSize to avoid creating too much
2689 // additional register pressure.
2690 return ClusterSize <= 4 && std::abs(Offset1 - Offset2) < CacheLineSize;
2691}
2692
2693// Set BaseReg (the base register operand), Offset (the byte offset being
2694// accessed) and the access Width of the passed instruction that reads/writes
2695// memory. Returns false if the instruction does not read/write memory or the
2696// BaseReg/Offset/Width can't be determined. Is not guaranteed to always
2697// recognise base operands and offsets in all cases.
2698// TODO: Add an IsScalable bool ref argument (like the equivalent AArch64
2699// function) and set it as appropriate.
2701 const MachineInstr &LdSt, const MachineOperand *&BaseReg, int64_t &Offset,
2702 LocationSize &Width, const TargetRegisterInfo *TRI) const {
2703 if (!LdSt.mayLoadOrStore())
2704 return false;
2705
2706 // Here we assume the standard RISC-V ISA, which uses a base+offset
2707 // addressing mode. You'll need to relax these conditions to support custom
2708 // load/store instructions.
2709 if (LdSt.getNumExplicitOperands() != 3)
2710 return false;
2711 if ((!LdSt.getOperand(1).isReg() && !LdSt.getOperand(1).isFI()) ||
2712 !LdSt.getOperand(2).isImm())
2713 return false;
2714
2715 if (!LdSt.hasOneMemOperand())
2716 return false;
2717
2718 Width = (*LdSt.memoperands_begin())->getSize();
2719 BaseReg = &LdSt.getOperand(1);
2720 Offset = LdSt.getOperand(2).getImm();
2721 return true;
2722}
2723
2725 const MachineInstr &MIa, const MachineInstr &MIb) const {
2726 assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
2727 assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");
2728
2731 return false;
2732
2733 // Retrieve the base register, offset from the base register and width. Width
2734 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4). If
2735 // base registers are identical, and the offset of a lower memory access +
2736 // the width doesn't overlap the offset of a higher memory access,
2737 // then the memory accesses are different.
2739 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
2740 int64_t OffsetA = 0, OffsetB = 0;
2741 LocationSize WidthA = 0, WidthB = 0;
2742 if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) &&
2743 getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) {
2744 if (BaseOpA->isIdenticalTo(*BaseOpB)) {
2745 int LowOffset = std::min(OffsetA, OffsetB);
2746 int HighOffset = std::max(OffsetA, OffsetB);
2747 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2748 if (LowWidth.hasValue() &&
2749 LowOffset + (int)LowWidth.getValue() <= HighOffset)
2750 return true;
2751 }
2752 }
2753 return false;
2754}
2755
2756std::pair<unsigned, unsigned>
2758 const unsigned Mask = RISCVII::MO_DIRECT_FLAG_MASK;
2759 return std::make_pair(TF & Mask, TF & ~Mask);
2760}
2761
2764 using namespace RISCVII;
2765 static const std::pair<unsigned, const char *> TargetFlags[] = {
2766 {MO_CALL, "riscv-call"},
2767 {MO_LO, "riscv-lo"},
2768 {MO_HI, "riscv-hi"},
2769 {MO_PCREL_LO, "riscv-pcrel-lo"},
2770 {MO_PCREL_HI, "riscv-pcrel-hi"},
2771 {MO_GOT_HI, "riscv-got-hi"},
2772 {MO_TPREL_LO, "riscv-tprel-lo"},
2773 {MO_TPREL_HI, "riscv-tprel-hi"},
2774 {MO_TPREL_ADD, "riscv-tprel-add"},
2775 {MO_TLS_GOT_HI, "riscv-tls-got-hi"},
2776 {MO_TLS_GD_HI, "riscv-tls-gd-hi"},
2777 {MO_TLSDESC_HI, "riscv-tlsdesc-hi"},
2778 {MO_TLSDESC_LOAD_LO, "riscv-tlsdesc-load-lo"},
2779 {MO_TLSDESC_ADD_LO, "riscv-tlsdesc-add-lo"},
2780 {MO_TLSDESC_CALL, "riscv-tlsdesc-call"}};
2781 return ArrayRef(TargetFlags);
2782}
2784 MachineFunction &MF, bool OutlineFromLinkOnceODRs) const {
2785 const Function &F = MF.getFunction();
2786
2787 // Can F be deduplicated by the linker? If it can, don't outline from it.
2788 if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage())
2789 return false;
2790
2791 // Don't outline from functions with section markings; the program could
2792 // expect that all the code is in the named section.
2793 if (F.hasSection())
2794 return false;
2795
2796 // It's safe to outline from MF.
2797 return true;
2798}
2799
2801 unsigned &Flags) const {
2802 // More accurate safety checking is done in getOutliningCandidateInfo.
2804}
2805
2806// Enum values indicating how an outlined call should be constructed.
2810
2812 MachineFunction &MF) const {
2813 return MF.getFunction().hasMinSize();
2814}
2815
2816std::optional<outliner::OutlinedFunction>
2818 std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
2819
2820 // First we need to filter out candidates where the X5 register (IE t0) can't
2821 // be used to setup the function call.
2822 auto CannotInsertCall = [](outliner::Candidate &C) {
2823 const TargetRegisterInfo *TRI = C.getMF()->getSubtarget().getRegisterInfo();
2824 return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *TRI);
2825 };
2826
2827 llvm::erase_if(RepeatedSequenceLocs, CannotInsertCall);
2828
2829 // If the sequence doesn't have enough candidates left, then we're done.
2830 if (RepeatedSequenceLocs.size() < 2)
2831 return std::nullopt;
2832
2833 unsigned SequenceSize = 0;
2834
2835 for (auto &MI : RepeatedSequenceLocs[0])
2836 SequenceSize += getInstSizeInBytes(MI);
2837
2838 // call t0, function = 8 bytes.
2839 unsigned CallOverhead = 8;
2840 for (auto &C : RepeatedSequenceLocs)
2841 C.setCallInfo(MachineOutlinerDefault, CallOverhead);
2842
2843 // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
2844 unsigned FrameOverhead = 4;
2845 if (RepeatedSequenceLocs[0]
2846 .getMF()
2847 ->getSubtarget<RISCVSubtarget>()
2848 .hasStdExtCOrZca())
2849 FrameOverhead = 2;
2850
2851 return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize,
2852 FrameOverhead, MachineOutlinerDefault);
2853}
2854
2857 unsigned Flags) const {
2858 MachineInstr &MI = *MBBI;
2859 MachineBasicBlock *MBB = MI.getParent();
2860 const TargetRegisterInfo *TRI =
2862 const auto &F = MI.getMF()->getFunction();
2863
2864 // We can manually strip out CFI instructions later.
2865 if (MI.isCFIInstruction())
2866 // If current function has exception handling code, we can't outline &
2867 // strip these CFI instructions since it may break .eh_frame section
2868 // needed in unwinding.
2869 return F.needsUnwindTableEntry() ? outliner::InstrType::Illegal
2871
2872 // We need support for tail calls to outlined functions before return
2873 // statements can be allowed.
2874 if (MI.isReturn())
2876
2877 // Don't allow modifying the X5 register which we use for return addresses for
2878 // these outlined functions.
2879 if (MI.modifiesRegister(RISCV::X5, TRI) ||
2880 MI.getDesc().hasImplicitDefOfPhysReg(RISCV::X5))
2882
2883 // Make sure the operands don't reference something unsafe.
2884 for (const auto &MO : MI.operands()) {
2885
2886 // pcrel-hi and pcrel-lo can't put in separate sections, filter that out
2887 // if any possible.
2888 if (MO.getTargetFlags() == RISCVII::MO_PCREL_LO &&
2889 (MI.getMF()->getTarget().getFunctionSections() || F.hasComdat() ||
2890 F.hasSection()))
2892 }
2893
2895}
2896
2899 const outliner::OutlinedFunction &OF) const {
2900
2901 // Strip out any CFI instructions
2902 bool Changed = true;
2903 while (Changed) {
2904 Changed = false;
2905 auto I = MBB.begin();
2906 auto E = MBB.end();
2907 for (; I != E; ++I) {
2908 if (I->isCFIInstruction()) {
2909 I->removeFromParent();
2910 Changed = true;
2911 break;
2912 }
2913 }
2914 }
2915
2916 MBB.addLiveIn(RISCV::X5);
2917
2918 // Add in a return instruction to the end of the outlined frame.
2919 MBB.insert(MBB.end(), BuildMI(MF, DebugLoc(), get(RISCV::JALR))
2920 .addReg(RISCV::X0, RegState::Define)
2921 .addReg(RISCV::X5)
2922 .addImm(0));
2923}
2924
2928
2929 // Add in a call instruction to the outlined function at the given location.
2930 It = MBB.insert(It,
2931 BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5)
2932 .addGlobalAddress(M.getNamedValue(MF.getName()), 0,
2934 return It;
2935}
2936
2937std::optional<RegImmPair> RISCVInstrInfo::isAddImmediate(const MachineInstr &MI,
2938 Register Reg) const {
2939 // TODO: Handle cases where Reg is a super- or sub-register of the
2940 // destination register.
2941 const MachineOperand &Op0 = MI.getOperand(0);
2942 if (!Op0.isReg() || Reg != Op0.getReg())
2943 return std::nullopt;
2944
2945 // Don't consider ADDIW as a candidate because the caller may not be aware
2946 // of its sign extension behaviour.
2947 if (MI.getOpcode() == RISCV::ADDI && MI.getOperand(1).isReg() &&
2948 MI.getOperand(2).isImm())
2949 return RegImmPair{MI.getOperand(1).getReg(), MI.getOperand(2).getImm()};
2950
2951 return std::nullopt;
2952}
2953
2954// MIR printer helper function to annotate Operands with a comment.
2956 const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx,
2957 const TargetRegisterInfo *TRI) const {
2958 // Print a generic comment for this operand if there is one.
2959 std::string GenericComment =
2961 if (!GenericComment.empty())
2962 return GenericComment;
2963
2964 // If not, we must have an immediate operand.
2965 if (!Op.isImm())
2966 return std::string();
2967
2968 std::string Comment;
2969 raw_string_ostream OS(Comment);
2970
2971 uint64_t TSFlags = MI.getDesc().TSFlags;
2972
2973 // Print the full VType operand of vsetvli/vsetivli instructions, and the SEW
2974 // operand of vector codegen pseudos.
2975 if ((MI.getOpcode() == RISCV::VSETVLI || MI.getOpcode() == RISCV::VSETIVLI ||
2976 MI.getOpcode() == RISCV::PseudoVSETVLI ||
2977 MI.getOpcode() == RISCV::PseudoVSETIVLI ||
2978 MI.getOpcode() == RISCV::PseudoVSETVLIX0) &&
2979 OpIdx == 2) {
2980 unsigned Imm = MI.getOperand(OpIdx).getImm();
2982 } else if (RISCVII::hasSEWOp(TSFlags) &&
2983 OpIdx == RISCVII::getSEWOpNum(MI.getDesc())) {
2984 unsigned Log2SEW = MI.getOperand(OpIdx).getImm();
2985 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
2986 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
2987 OS << "e" << SEW;
2988 } else if (RISCVII::hasVecPolicyOp(TSFlags) &&
2989 OpIdx == RISCVII::getVecPolicyOpNum(MI.getDesc())) {
2990 unsigned Policy = MI.getOperand(OpIdx).getImm();
2992 "Invalid Policy Value");
2993 OS << (Policy & RISCVII::TAIL_AGNOSTIC ? "ta" : "tu") << ", "
2994 << (Policy & RISCVII::MASK_AGNOSTIC ? "ma" : "mu");
2995 }
2996
2997 OS.flush();
2998 return Comment;
2999}
3000
3001// clang-format off
3002#define CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL) \
3003 RISCV::Pseudo##OP##_##LMUL
3004
3005#define CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL) \
3006 RISCV::Pseudo##OP##_##LMUL##_MASK
3007
3008#define CASE_RVV_OPCODE_LMUL(OP, LMUL) \
3009 CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL): \
3010 case CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL)
3011
3012#define CASE_RVV_OPCODE_UNMASK_WIDEN(OP) \
3013 CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF8): \
3014 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF4): \
3015 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF2): \
3016 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M1): \
3017 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M2): \
3018 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M4)
3019
3020#define CASE_RVV_OPCODE_UNMASK(OP) \
3021 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
3022 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M8)
3023
3024#define CASE_RVV_OPCODE_MASK_WIDEN(OP) \
3025 CASE_RVV_OPCODE_MASK_LMUL(OP, MF8): \
3026 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF4): \
3027 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF2): \
3028 case CASE_RVV_OPCODE_MASK_LMUL(OP, M1): \
3029 case CASE_RVV_OPCODE_MASK_LMUL(OP, M2): \
3030 case CASE_RVV_OPCODE_MASK_LMUL(OP, M4)
3031
3032#define CASE_RVV_OPCODE_MASK(OP) \
3033 CASE_RVV_OPCODE_MASK_WIDEN(OP): \
3034 case CASE_RVV_OPCODE_MASK_LMUL(OP, M8)
3035
3036#define CASE_RVV_OPCODE_WIDEN(OP) \
3037 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
3038 case CASE_RVV_OPCODE_MASK_WIDEN(OP)
3039
3040#define CASE_RVV_OPCODE(OP) \
3041 CASE_RVV_OPCODE_UNMASK(OP): \
3042 case CASE_RVV_OPCODE_MASK(OP)
3043// clang-format on
3044
3045// clang-format off
3046#define CASE_VMA_OPCODE_COMMON(OP, TYPE, LMUL) \
3047 RISCV::PseudoV##OP##_##TYPE##_##LMUL
3048
3049#define CASE_VMA_OPCODE_LMULS_M1(OP, TYPE) \
3050 CASE_VMA_OPCODE_COMMON(OP, TYPE, M1): \
3051 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M2): \
3052 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M4): \
3053 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M8)
3054
3055#define CASE_VMA_OPCODE_LMULS_MF2(OP, TYPE) \
3056 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF2): \
3057 case CASE_VMA_OPCODE_LMULS_M1(OP, TYPE)
3058
3059#define CASE_VMA_OPCODE_LMULS_MF4(OP, TYPE) \
3060 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF4): \
3061 case CASE_VMA_OPCODE_LMULS_MF2(OP, TYPE)
3062
3063#define CASE_VMA_OPCODE_LMULS(OP, TYPE) \
3064 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF8): \
3065 case CASE_VMA_OPCODE_LMULS_MF4(OP, TYPE)
3066
3067// VFMA instructions are SEW specific.
3068#define CASE_VFMA_OPCODE_COMMON(OP, TYPE, LMUL, SEW) \
3069 RISCV::PseudoV##OP##_##TYPE##_##LMUL##_##SEW
3070
3071#define CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW) \
3072 CASE_VFMA_OPCODE_COMMON(OP, TYPE, M1, SEW): \
3073 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M2, SEW): \
3074 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M4, SEW): \
3075 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M8, SEW)
3076
3077#define CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW) \
3078 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF2, SEW): \
3079 case CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW)
3080
3081#define CASE_VFMA_OPCODE_LMULS_MF4(OP, TYPE, SEW) \
3082 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF4, SEW): \
3083 case CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW)
3084
3085#define CASE_VFMA_OPCODE_VV(OP) \
3086 CASE_VFMA_OPCODE_LMULS_MF4(OP, VV, E16): \
3087 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VV, E32): \
3088 case CASE_VFMA_OPCODE_LMULS_M1(OP, VV, E64)
3089
3090#define CASE_VFMA_SPLATS(OP) \
3091 CASE_VFMA_OPCODE_LMULS_MF4(OP, VFPR16, E16): \
3092 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VFPR32, E32): \
3093 case CASE_VFMA_OPCODE_LMULS_M1(OP, VFPR64, E64)
3094// clang-format on
3095
3097 unsigned &SrcOpIdx1,
3098 unsigned &SrcOpIdx2) const {
3099 const MCInstrDesc &Desc = MI.getDesc();
3100 if (!Desc.isCommutable())
3101 return false;
3102
3103 switch (MI.getOpcode()) {
3104 case RISCV::TH_MVEQZ:
3105 case RISCV::TH_MVNEZ:
3106 // We can't commute operands if operand 2 (i.e., rs1 in
3107 // mveqz/mvnez rd,rs1,rs2) is the zero-register (as it is
3108 // not valid as the in/out-operand 1).
3109 if (MI.getOperand(2).getReg() == RISCV::X0)
3110 return false;
3111 // Operands 1 and 2 are commutable, if we switch the opcode.
3112 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
3113 case RISCV::TH_MULA:
3114 case RISCV::TH_MULAW:
3115 case RISCV::TH_MULAH:
3116 case RISCV::TH_MULS:
3117 case RISCV::TH_MULSW:
3118 case RISCV::TH_MULSH:
3119 // Operands 2 and 3 are commutable.
3120 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
3121 case RISCV::PseudoCCMOVGPRNoX0:
3122 case RISCV::PseudoCCMOVGPR:
3123 // Operands 4 and 5 are commutable.
3124 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 4, 5);
3125 case CASE_RVV_OPCODE(VADD_VV):
3126 case CASE_RVV_OPCODE(VAND_VV):
3127 case CASE_RVV_OPCODE(VOR_VV):
3128 case CASE_RVV_OPCODE(VXOR_VV):
3129 case CASE_RVV_OPCODE_MASK(VMSEQ_VV):
3130 case CASE_RVV_OPCODE_MASK(VMSNE_VV):
3131 case CASE_RVV_OPCODE(VMIN_VV):
3132 case CASE_RVV_OPCODE(VMINU_VV):
3133 case CASE_RVV_OPCODE(VMAX_VV):
3134 case CASE_RVV_OPCODE(VMAXU_VV):
3135 case CASE_RVV_OPCODE(VMUL_VV):
3136 case CASE_RVV_OPCODE(VMULH_VV):
3137 case CASE_RVV_OPCODE(VMULHU_VV):
3138 case CASE_RVV_OPCODE_WIDEN(VWADD_VV):
3139 case CASE_RVV_OPCODE_WIDEN(VWADDU_VV):
3140 case CASE_RVV_OPCODE_WIDEN(VWMUL_VV):
3141 case CASE_RVV_OPCODE_WIDEN(VWMULU_VV):
3142 case CASE_RVV_OPCODE_WIDEN(VWMACC_VV):
3143 case CASE_RVV_OPCODE_WIDEN(VWMACCU_VV):
3144 case CASE_RVV_OPCODE_UNMASK(VADC_VVM):
3145 case CASE_RVV_OPCODE(VSADD_VV):
3146 case CASE_RVV_OPCODE(VSADDU_VV):
3147 case CASE_RVV_OPCODE(VAADD_VV):
3148 case CASE_RVV_OPCODE(VAADDU_VV):
3149 case CASE_RVV_OPCODE(VSMUL_VV):
3150 // Operands 2 and 3 are commutable.
3151 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
3152 case CASE_VFMA_SPLATS(FMADD):
3153 case CASE_VFMA_SPLATS(FMSUB):
3154 case CASE_VFMA_SPLATS(FMACC):
3155 case CASE_VFMA_SPLATS(FMSAC):
3158 case CASE_VFMA_SPLATS(FNMACC):
3159 case CASE_VFMA_SPLATS(FNMSAC):
3160 case CASE_VFMA_OPCODE_VV(FMACC):
3161 case CASE_VFMA_OPCODE_VV(FMSAC):
3162 case CASE_VFMA_OPCODE_VV(FNMACC):
3163 case CASE_VFMA_OPCODE_VV(FNMSAC):
3164 case CASE_VMA_OPCODE_LMULS(MADD, VX):
3165 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
3166 case CASE_VMA_OPCODE_LMULS(MACC, VX):
3167 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
3168 case CASE_VMA_OPCODE_LMULS(MACC, VV):
3169 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
3170 // If the tail policy is undisturbed we can't commute.
3171 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
3172 if ((MI.getOperand(MI.getNumExplicitOperands() - 1).getImm() & 1) == 0)
3173 return false;
3174
3175 // For these instructions we can only swap operand 1 and operand 3 by
3176 // changing the opcode.
3177 unsigned CommutableOpIdx1 = 1;
3178 unsigned CommutableOpIdx2 = 3;
3179 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
3180 CommutableOpIdx2))
3181 return false;
3182 return true;
3183 }
3184 case CASE_VFMA_OPCODE_VV(FMADD):
3188 case CASE_VMA_OPCODE_LMULS(MADD, VV):
3189 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
3190 // If the tail policy is undisturbed we can't commute.
3191 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
3192 if ((MI.getOperand(MI.getNumExplicitOperands() - 1).getImm() & 1) == 0)
3193 return false;
3194
3195 // For these instructions we have more freedom. We can commute with the
3196 // other multiplicand or with the addend/subtrahend/minuend.
3197
3198 // Any fixed operand must be from source 1, 2 or 3.
3199 if (SrcOpIdx1 != CommuteAnyOperandIndex && SrcOpIdx1 > 3)
3200 return false;
3201 if (SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx2 > 3)
3202 return false;
3203
3204 // It both ops are fixed one must be the tied source.
3205 if (SrcOpIdx1 != CommuteAnyOperandIndex &&
3206 SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx1 != 1 && SrcOpIdx2 != 1)
3207 return false;
3208
3209 // Look for two different register operands assumed to be commutable
3210 // regardless of the FMA opcode. The FMA opcode is adjusted later if
3211 // needed.
3212 if (SrcOpIdx1 == CommuteAnyOperandIndex ||
3213 SrcOpIdx2 == CommuteAnyOperandIndex) {
3214 // At least one of operands to be commuted is not specified and
3215 // this method is free to choose appropriate commutable operands.
3216 unsigned CommutableOpIdx1 = SrcOpIdx1;
3217 if (SrcOpIdx1 == SrcOpIdx2) {
3218 // Both of operands are not fixed. Set one of commutable
3219 // operands to the tied source.
3220 CommutableOpIdx1 = 1;
3221 } else if (SrcOpIdx1 == CommuteAnyOperandIndex) {
3222 // Only one of the operands is not fixed.
3223 CommutableOpIdx1 = SrcOpIdx2;
3224 }
3225
3226 // CommutableOpIdx1 is well defined now. Let's choose another commutable
3227 // operand and assign its index to CommutableOpIdx2.
3228 unsigned CommutableOpIdx2;
3229 if (CommutableOpIdx1 != 1) {
3230 // If we haven't already used the tied source, we must use it now.
3231 CommutableOpIdx2 = 1;
3232 } else {
3233 Register Op1Reg = MI.getOperand(CommutableOpIdx1).getReg();
3234
3235 // The commuted operands should have different registers.
3236 // Otherwise, the commute transformation does not change anything and
3237 // is useless. We use this as a hint to make our decision.
3238 if (Op1Reg != MI.getOperand(2).getReg())
3239 CommutableOpIdx2 = 2;
3240 else
3241 CommutableOpIdx2 = 3;
3242 }
3243
3244 // Assign the found pair of commutable indices to SrcOpIdx1 and
3245 // SrcOpIdx2 to return those values.
3246 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
3247 CommutableOpIdx2))
3248 return false;
3249 }
3250
3251 return true;
3252 }
3253 }
3254
3255 return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
3256}
3257
3258// clang-format off
3259#define CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL) \
3260 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL: \
3261 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL; \
3262 break;
3263
3264#define CASE_VMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE) \
3265 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1) \
3266 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2) \
3267 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4) \
3268 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8)
3269
3270#define CASE_VMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE) \
3271 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2) \
3272 CASE_VMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE)
3273
3274#define CASE_VMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE) \
3275 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4) \
3276 CASE_VMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE)
3277
3278#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE) \
3279 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8) \
3280 CASE_VMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE)
3281
3282#define CASE_VMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
3283 CASE_VMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16) \
3284 CASE_VMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32) \
3285 CASE_VMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64)
3286
3287// VFMA depends on SEW.
3288#define CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL, SEW) \
3289 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL##_##SEW: \
3290 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL##_##SEW; \
3291 break;
3292
3293#define CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW) \
3294 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1, SEW) \
3295 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2, SEW) \
3296 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4, SEW) \
3297 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8, SEW)
3298
3299#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW) \
3300 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2, SEW) \
3301 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW)
3302
3303#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP) \
3304 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VV, E16) \
3305 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VV, E32) \
3306 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VV, E64)
3307
3308#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW) \
3309 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4, SEW) \
3310 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW)
3311
3312#define CASE_VFMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE, SEW) \
3313 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8, SEW) \
3314 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW)
3315
3316#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
3317 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
3318 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
3319 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
3320
3322 bool NewMI,
3323 unsigned OpIdx1,
3324 unsigned OpIdx2) const {
3325 auto cloneIfNew = [NewMI](MachineInstr &MI) -> MachineInstr & {
3326 if (NewMI)
3327 return *MI.getParent()->getParent()->CloneMachineInstr(&MI);
3328 return MI;
3329 };
3330
3331 switch (MI.getOpcode()) {
3332 case RISCV::TH_MVEQZ:
3333 case RISCV::TH_MVNEZ: {
3334 auto &WorkingMI = cloneIfNew(MI);
3335 WorkingMI.setDesc(get(MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
3336 : RISCV::TH_MVEQZ));
3337 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, false, OpIdx1,
3338 OpIdx2);
3339 }
3340 case RISCV::PseudoCCMOVGPRNoX0:
3341 case RISCV::PseudoCCMOVGPR: {
3342 // CCMOV can be commuted by inverting the condition.
3343 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
3345 auto &WorkingMI = cloneIfNew(MI);
3346 WorkingMI.getOperand(3).setImm(CC);
3347 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI*/ false,
3348 OpIdx1, OpIdx2);
3349 }
3350 case CASE_VFMA_SPLATS(FMACC):
3351 case CASE_VFMA_SPLATS(FMADD):
3352 case CASE_VFMA_SPLATS(FMSAC):
3353 case CASE_VFMA_SPLATS(FMSUB):
3354 case CASE_VFMA_SPLATS(FNMACC):
3356 case CASE_VFMA_SPLATS(FNMSAC):
3358 case CASE_VFMA_OPCODE_VV(FMACC):
3359 case CASE_VFMA_OPCODE_VV(FMSAC):
3360 case CASE_VFMA_OPCODE_VV(FNMACC):
3361 case CASE_VFMA_OPCODE_VV(FNMSAC):
3362 case CASE_VMA_OPCODE_LMULS(MADD, VX):
3363 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
3364 case CASE_VMA_OPCODE_LMULS(MACC, VX):
3365 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
3366 case CASE_VMA_OPCODE_LMULS(MACC, VV):
3367 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
3368 // It only make sense to toggle these between clobbering the
3369 // addend/subtrahend/minuend one of the multiplicands.
3370 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
3371 assert((OpIdx1 == 3 || OpIdx2 == 3) && "Unexpected opcode index");
3372 unsigned Opc;
3373 switch (MI.getOpcode()) {
3374 default:
3375 llvm_unreachable("Unexpected opcode");
3376 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMACC, FMADD)
3377 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMADD, FMACC)
3384 CASE_VFMA_CHANGE_OPCODE_VV(FMACC, FMADD)
3388 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VX)
3389 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VX)
3390 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VX)
3391 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VX)
3392 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VV)
3393 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VV)
3394 }
3395
3396 auto &WorkingMI = cloneIfNew(MI);
3397 WorkingMI.setDesc(get(Opc));
3398 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
3399 OpIdx1, OpIdx2);
3400 }
3401 case CASE_VFMA_OPCODE_VV(FMADD):
3405 case CASE_VMA_OPCODE_LMULS(MADD, VV):
3406 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
3407 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
3408 // If one of the operands, is the addend we need to change opcode.
3409 // Otherwise we're just swapping 2 of the multiplicands.
3410 if (OpIdx1 == 3 || OpIdx2 == 3) {
3411 unsigned Opc;
3412 switch (MI.getOpcode()) {
3413 default:
3414 llvm_unreachable("Unexpected opcode");
3415 CASE_VFMA_CHANGE_OPCODE_VV(FMADD, FMACC)
3419 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VV)
3420 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VV)
3421 }
3422
3423 auto &WorkingMI = cloneIfNew(MI);
3424 WorkingMI.setDesc(get(Opc));
3425 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
3426 OpIdx1, OpIdx2);
3427 }
3428 // Let the default code handle it.
3429 break;
3430 }
3431 }
3432
3433 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
3434}
3435
3436#undef CASE_RVV_OPCODE_UNMASK_LMUL
3437#undef CASE_RVV_OPCODE_MASK_LMUL
3438#undef CASE_RVV_OPCODE_LMUL
3439#undef CASE_RVV_OPCODE_UNMASK_WIDEN
3440#undef CASE_RVV_OPCODE_UNMASK
3441#undef CASE_RVV_OPCODE_MASK_WIDEN
3442#undef CASE_RVV_OPCODE_MASK
3443#undef CASE_RVV_OPCODE_WIDEN
3444#undef CASE_RVV_OPCODE
3445
3446#undef CASE_VMA_OPCODE_COMMON
3447#undef CASE_VMA_OPCODE_LMULS_M1
3448#undef CASE_VMA_OPCODE_LMULS_MF2
3449#undef CASE_VMA_OPCODE_LMULS_MF4
3450#undef CASE_VMA_OPCODE_LMULS
3451#undef CASE_VFMA_OPCODE_COMMON
3452#undef CASE_VFMA_OPCODE_LMULS_M1
3453#undef CASE_VFMA_OPCODE_LMULS_MF2
3454#undef CASE_VFMA_OPCODE_LMULS_MF4
3455#undef CASE_VFMA_OPCODE_VV
3456#undef CASE_VFMA_SPLATS
3457
3458// clang-format off
3459#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
3460 RISCV::PseudoV##OP##_##LMUL##_TIED
3461
3462#define CASE_WIDEOP_OPCODE_LMULS_MF4(OP) \
3463 CASE_WIDEOP_OPCODE_COMMON(OP, MF4): \
3464 case CASE_WIDEOP_OPCODE_COMMON(OP, MF2): \
3465 case CASE_WIDEOP_OPCODE_COMMON(OP, M1): \
3466 case CASE_WIDEOP_OPCODE_COMMON(OP, M2): \
3467 case CASE_WIDEOP_OPCODE_COMMON(OP, M4)
3468
3469#define CASE_WIDEOP_OPCODE_LMULS(OP) \
3470 CASE_WIDEOP_OPCODE_COMMON(OP, MF8): \
3471 case CASE_WIDEOP_OPCODE_LMULS_MF4(OP)
3472
3473#define CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL) \
3474 case RISCV::PseudoV##OP##_##LMUL##_TIED: \
3475 NewOpc = RISCV::PseudoV##OP##_##LMUL; \
3476 break;
3477
3478#define CASE_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP) \
3479 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4) \
3480 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2) \
3481 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1) \
3482 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2) \
3483 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4)
3484
3485#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
3486 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF8) \
3487 CASE_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP)
3488
3489// FP Widening Ops may by SEW aware. Create SEW aware cases for these cases.
3490#define CASE_FP_WIDEOP_OPCODE_COMMON(OP, LMUL, SEW) \
3491 RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED
3492
3493#define CASE_FP_WIDEOP_OPCODE_LMULS_MF4(OP) \
3494 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
3495 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
3496 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E32): \
3497 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
3498 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E32): \
3499 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
3500 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E32): \
3501 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16): \
3502 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E32) \
3503
3504#define CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL, SEW) \
3505 case RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED: \
3506 NewOpc = RISCV::PseudoV##OP##_##LMUL##_##SEW; \
3507 break;
3508
3509#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP) \
3510 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
3511 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
3512 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E32) \
3513 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
3514 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E32) \
3515 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
3516 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E32) \
3517 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16) \
3518 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E32) \
3519
3520#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
3521 CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP)
3522// clang-format on
3523
3525 LiveVariables *LV,
3526 LiveIntervals *LIS) const {
3528 switch (MI.getOpcode()) {
3529 default:
3530 return nullptr;
3531 case CASE_FP_WIDEOP_OPCODE_LMULS_MF4(FWADD_WV):
3532 case CASE_FP_WIDEOP_OPCODE_LMULS_MF4(FWSUB_WV): {
3533 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
3534 MI.getNumExplicitOperands() == 7 &&
3535 "Expect 7 explicit operands rd, rs2, rs1, rm, vl, sew, policy");
3536 // If the tail policy is undisturbed we can't convert.
3537 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
3538 1) == 0)
3539 return nullptr;
3540 // clang-format off
3541 unsigned NewOpc;
3542 switch (MI.getOpcode()) {
3543 default:
3544 llvm_unreachable("Unexpected opcode");
3547 }
3548 // clang-format on
3549
3550 MachineBasicBlock &MBB = *MI.getParent();
3551 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
3552 .add(MI.getOperand(0))
3553 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
3554 .add(MI.getOperand(1))
3555 .add(MI.getOperand(2))
3556 .add(MI.getOperand(3))
3557 .add(MI.getOperand(4))
3558 .add(MI.getOperand(5))
3559 .add(MI.getOperand(6));
3560 break;
3561 }
3562 case CASE_WIDEOP_OPCODE_LMULS(WADD_WV):
3563 case CASE_WIDEOP_OPCODE_LMULS(WADDU_WV):
3564 case CASE_WIDEOP_OPCODE_LMULS(WSUB_WV):
3565 case CASE_WIDEOP_OPCODE_LMULS(WSUBU_WV): {
3566 // If the tail policy is undisturbed we can't convert.
3567 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
3568 MI.getNumExplicitOperands() == 6);
3569 if ((MI.getOperand(5).getImm() & 1) == 0)
3570 return nullptr;
3571
3572 // clang-format off
3573 unsigned NewOpc;
3574 switch (MI.getOpcode()) {
3575 default:
3576 llvm_unreachable("Unexpected opcode");
3581 }
3582 // clang-format on
3583
3584 MachineBasicBlock &MBB = *MI.getParent();
3585 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
3586 .add(MI.getOperand(0))
3587 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
3588 .add(MI.getOperand(1))
3589 .add(MI.getOperand(2))
3590 .add(MI.getOperand(3))
3591 .add(MI.getOperand(4))
3592 .add(MI.getOperand(5));
3593 break;
3594 }
3595 }
3596 MIB.copyImplicitOps(MI);
3597
3598 if (LV) {
3599 unsigned NumOps = MI.getNumOperands();
3600 for (unsigned I = 1; I < NumOps; ++I) {
3601 MachineOperand &Op = MI.getOperand(I);
3602 if (Op.isReg() && Op.isKill())
3603 LV->replaceKillInstruction(Op.getReg(), MI, *MIB);
3604 }
3605 }
3606
3607 if (LIS) {
3609
3610 if (MI.getOperand(0).isEarlyClobber()) {
3611 // Use operand 1 was tied to early-clobber def operand 0, so its live
3612 // interval could have ended at an early-clobber slot. Now they are not
3613 // tied we need to update it to the normal register slot.
3614 LiveInterval &LI = LIS->getInterval(MI.getOperand(1).getReg());
3616 if (S->end == Idx.getRegSlot(true))
3617 S->end = Idx.getRegSlot();
3618 }
3619 }
3620
3621 return MIB;
3622}
3623
3624#undef CASE_WIDEOP_OPCODE_COMMON
3625#undef CASE_WIDEOP_OPCODE_LMULS_MF4
3626#undef CASE_WIDEOP_OPCODE_LMULS
3627#undef CASE_WIDEOP_CHANGE_OPCODE_COMMON
3628#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS_MF4
3629#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS
3630#undef CASE_FP_WIDEOP_OPCODE_COMMON
3631#undef CASE_FP_WIDEOP_OPCODE_LMULS_MF4
3632#undef CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON
3633#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4
3634#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS
3635
3638 Register DestReg, uint32_t Amount,
3639 MachineInstr::MIFlag Flag) const {
3641 if (llvm::has_single_bit<uint32_t>(Amount)) {
3642 uint32_t ShiftAmount = Log2_32(Amount);
3643 if (ShiftAmount == 0)
3644 return;
3645 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
3646 .addReg(DestReg, RegState::Kill)
3647 .addImm(ShiftAmount)
3648 .setMIFlag(Flag);
3649 } else if (STI.hasStdExtZba() &&
3650 ((Amount % 3 == 0 && isPowerOf2_64(Amount / 3)) ||
3651 (Amount % 5 == 0 && isPowerOf2_64(Amount / 5)) ||
3652 (Amount % 9 == 0 && isPowerOf2_64(Amount / 9)))) {
3653 // We can use Zba SHXADD+SLLI instructions for multiply in some cases.
3654 unsigned Opc;
3655 uint32_t ShiftAmount;
3656 if (Amount % 9 == 0) {
3657 Opc = RISCV::SH3ADD;
3658 ShiftAmount = Log2_64(Amount / 9);
3659 } else if (Amount % 5 == 0) {
3660 Opc = RISCV::SH2ADD;
3661 ShiftAmount = Log2_64(Amount / 5);
3662 } else if (Amount % 3 == 0) {
3663 Opc = RISCV::SH1ADD;
3664 ShiftAmount = Log2_64(Amount / 3);
3665 } else {
3666 llvm_unreachable("implied by if-clause");
3667 }
3668 if (ShiftAmount)
3669 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
3670 .addReg(DestReg, RegState::Kill)
3671 .addImm(ShiftAmount)
3672 .setMIFlag(Flag);
3673 BuildMI(MBB, II, DL, get(Opc), DestReg)
3674 .addReg(DestReg, RegState::Kill)
3675 .addReg(DestReg)
3676 .setMIFlag(Flag);
3677 } else if (llvm::has_single_bit<uint32_t>(Amount - 1)) {
3678 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
3679 uint32_t ShiftAmount = Log2_32(Amount - 1);
3680 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
3681 .addReg(DestReg)
3682 .addImm(ShiftAmount)
3683 .setMIFlag(Flag);
3684 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
3685 .addReg(ScaledRegister, RegState::Kill)
3686 .addReg(DestReg, RegState::Kill)
3687 .setMIFlag(Flag);
3688 } else if (llvm::has_single_bit<uint32_t>(Amount + 1)) {
3689 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
3690 uint32_t ShiftAmount = Log2_32(Amount + 1);
3691 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
3692 .addReg(DestReg)
3693 .addImm(ShiftAmount)
3694 .setMIFlag(Flag);
3695 BuildMI(MBB, II, DL, get(RISCV::SUB), DestReg)
3696 .addReg(ScaledRegister, RegState::Kill)
3697 .addReg(DestReg, RegState::Kill)
3698 .setMIFlag(Flag);
3699 } else if (STI.hasStdExtZmmul()) {
3700 Register N = MRI.createVirtualRegister(&RISCV::GPRRegClass);
3701 movImm(MBB, II, DL, N, Amount, Flag);
3702 BuildMI(MBB, II, DL, get(RISCV::MUL), DestReg)
3703 .addReg(DestReg, RegState::Kill)
3705 .setMIFlag(Flag);
3706 } else {
3707 Register Acc;
3708 uint32_t PrevShiftAmount = 0;
3709 for (uint32_t ShiftAmount = 0; Amount >> ShiftAmount; ShiftAmount++) {
3710 if (Amount & (1U << ShiftAmount)) {
3711 if (ShiftAmount)
3712 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
3713 .addReg(DestReg, RegState::Kill)
3714 .addImm(ShiftAmount - PrevShiftAmount)
3715 .setMIFlag(Flag);
3716 if (Amount >> (ShiftAmount + 1)) {
3717 // If we don't have an accmulator yet, create it and copy DestReg.
3718 if (!Acc) {
3719 Acc = MRI.createVirtualRegister(&RISCV::GPRRegClass);
3720 BuildMI(MBB, II, DL, get(TargetOpcode::COPY), Acc)
3721 .addReg(DestReg)
3722 .setMIFlag(Flag);
3723 } else {
3724 BuildMI(MBB, II, DL, get(RISCV::ADD), Acc)
3725 .addReg(Acc, RegState::Kill)
3726 .addReg(DestReg)
3727 .setMIFlag(Flag);
3728 }
3729 }
3730 PrevShiftAmount = ShiftAmount;
3731 }
3732 }
3733 assert(Acc && "Expected valid accumulator");
3734 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
3735 .addReg(DestReg, RegState::Kill)
3736 .addReg(Acc, RegState::Kill)
3737 .setMIFlag(Flag);
3738 }
3739}
3740
3743 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
3744 {{MONontemporalBit0, "riscv-nontemporal-domain-bit-0"},
3745 {MONontemporalBit1, "riscv-nontemporal-domain-bit-1"}};
3746 return ArrayRef(TargetFlags);
3747}
3748
3749// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
3751 return MI.getOpcode() == RISCV::ADDIW && MI.getOperand(1).isReg() &&
3752 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0;
3753}
3754
3755// Returns true if this is the zext.w pattern, adduw rd, rs1, x0.
3757 return MI.getOpcode() == RISCV::ADD_UW && MI.getOperand(1).isReg() &&
3758 MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0;
3759}
3760
3761// Returns true if this is the zext.b pattern, andi rd, rs1, 255.
3763 return MI.getOpcode() == RISCV::ANDI && MI.getOperand(1).isReg() &&
3764 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 255;
3765}
3766
3767static bool isRVVWholeLoadStore(unsigned Opcode) {
3768 switch (Opcode) {
3769 default:
3770 return false;
3771 case RISCV::VS1R_V:
3772 case RISCV::VS2R_V:
3773 case RISCV::VS4R_V:
3774 case RISCV::VS8R_V:
3775 case RISCV::VL1RE8_V:
3776 case RISCV::VL2RE8_V:
3777 case RISCV::VL4RE8_V:
3778 case RISCV::VL8RE8_V:
3779 case RISCV::VL1RE16_V:
3780 case RISCV::VL2RE16_V:
3781 case RISCV::VL4RE16_V:
3782 case RISCV::VL8RE16_V:
3783 case RISCV::VL1RE32_V:
3784 case RISCV::VL2RE32_V:
3785 case RISCV::VL4RE32_V:
3786 case RISCV::VL8RE32_V:
3787 case RISCV::VL1RE64_V:
3788 case RISCV::VL2RE64_V:
3789 case RISCV::VL4RE64_V:
3790 case RISCV::VL8RE64_V:
3791 return true;
3792 }
3793}
3794
3796 // RVV lacks any support for immediate addressing for stack addresses, so be
3797 // conservative.
3798 unsigned Opcode = MI.getOpcode();
3799 if (!RISCVVPseudosTable::getPseudoInfo(Opcode) &&
3800 !isRVVWholeLoadStore(Opcode) && !isRVVSpillForZvlsseg(Opcode))
3801 return false;
3802 return true;
3803}
3804
3805std::optional<std::pair<unsigned, unsigned>>
3807 switch (Opcode) {
3808 default:
3809 return std::nullopt;
3810 case RISCV::PseudoVSPILL2_M1:
3811 case RISCV::PseudoVRELOAD2_M1:
3812 return std::make_pair(2u, 1u);
3813 case RISCV::PseudoVSPILL2_M2:
3814 case RISCV::PseudoVRELOAD2_M2:
3815 return std::make_pair(2u, 2u);
3816 case RISCV::PseudoVSPILL2_M4:
3817 case RISCV::PseudoVRELOAD2_M4:
3818 return std::make_pair(2u, 4u);
3819 case RISCV::PseudoVSPILL3_M1:
3820 case RISCV::PseudoVRELOAD3_M1:
3821 return std::make_pair(3u, 1u);
3822 case RISCV::PseudoVSPILL3_M2:
3823 case RISCV::PseudoVRELOAD3_M2:
3824 return std::make_pair(3u, 2u);
3825 case RISCV::PseudoVSPILL4_M1:
3826 case RISCV::PseudoVRELOAD4_M1:
3827 return std::make_pair(4u, 1u);
3828 case RISCV::PseudoVSPILL4_M2:
3829 case RISCV::PseudoVRELOAD4_M2:
3830 return std::make_pair(4u, 2u);
3831 case RISCV::PseudoVSPILL5_M1:
3832 case RISCV::PseudoVRELOAD5_M1:
3833 return std::make_pair(5u, 1u);
3834 case RISCV::PseudoVSPILL6_M1:
3835 case RISCV::PseudoVRELOAD6_M1:
3836 return std::make_pair(6u, 1u);
3837 case RISCV::PseudoVSPILL7_M1:
3838 case RISCV::PseudoVRELOAD7_M1:
3839 return std::make_pair(7u, 1u);
3840 case RISCV::PseudoVSPILL8_M1:
3841 case RISCV::PseudoVRELOAD8_M1:
3842 return std::make_pair(8u, 1u);
3843 }
3844}
3845
3847 return MI.getNumExplicitDefs() == 2 &&
3848 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) && !MI.isInlineAsm();
3849}
3850
3851bool RISCV::hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2) {
3852 int16_t MI1FrmOpIdx =
3853 RISCV::getNamedOperandIdx(MI1.getOpcode(), RISCV::OpName::frm);
3854 int16_t MI2FrmOpIdx =
3855 RISCV::getNamedOperandIdx(MI2.getOpcode(), RISCV::OpName::frm);
3856 if (MI1FrmOpIdx < 0 || MI2FrmOpIdx < 0)
3857 return false;
3858 MachineOperand FrmOp1 = MI1.getOperand(MI1FrmOpIdx);
3859 MachineOperand FrmOp2 = MI2.getOperand(MI2FrmOpIdx);
3860 return FrmOp1.getImm() == FrmOp2.getImm();
3861}
3862
3863std::optional<unsigned>
3865 // TODO: Handle Zvbb instructions
3866 switch (Opcode) {
3867 default:
3868 return std::nullopt;
3869
3870 // 11.6. Vector Single-Width Shift Instructions
3871 case RISCV::VSLL_VX:
3872 case RISCV::VSRL_VX:
3873 case RISCV::VSRA_VX:
3874 // 12.4. Vector Single-Width Scaling Shift Instructions
3875 case RISCV::VSSRL_VX:
3876 case RISCV::VSSRA_VX:
3877 // Only the low lg2(SEW) bits of the shift-amount value are used.
3878 return Log2SEW;
3879
3880 // 11.7 Vector Narrowing Integer Right Shift Instructions
3881 case RISCV::VNSRL_WX:
3882 case RISCV::VNSRA_WX:
3883 // 12.5. Vector Narrowing Fixed-Point Clip Instructions
3884 case RISCV::VNCLIPU_WX:
3885 case RISCV::VNCLIP_WX:
3886 // Only the low lg2(2*SEW) bits of the shift-amount value are used.
3887 return Log2SEW + 1;
3888
3889 // 11.1. Vector Single-Width Integer Add and Subtract
3890 case RISCV::VADD_VX:
3891 case RISCV::VSUB_VX:
3892 case RISCV::VRSUB_VX:
3893 // 11.2. Vector Widening Integer Add/Subtract
3894 case RISCV::VWADDU_VX:
3895 case RISCV::VWSUBU_VX:
3896 case RISCV::VWADD_VX:
3897 case RISCV::VWSUB_VX:
3898 case RISCV::VWADDU_WX:
3899 case RISCV::VWSUBU_WX:
3900 case RISCV::VWADD_WX:
3901 case RISCV::VWSUB_WX:
3902 // 11.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
3903 case RISCV::VADC_VXM:
3904 case RISCV::VADC_VIM:
3905 case RISCV::VMADC_VXM:
3906 case RISCV::VMADC_VIM:
3907 case RISCV::VMADC_VX:
3908 case RISCV::VSBC_VXM:
3909 case RISCV::VMSBC_VXM:
3910 case RISCV::VMSBC_VX:
3911 // 11.5 Vector Bitwise Logical Instructions
3912 case RISCV::VAND_VX:
3913 case RISCV::VOR_VX:
3914 case RISCV::VXOR_VX:
3915 // 11.8. Vector Integer Compare Instructions
3916 case RISCV::VMSEQ_VX:
3917 case RISCV::VMSNE_VX:
3918 case RISCV::VMSLTU_VX:
3919 case RISCV::VMSLT_VX:
3920 case RISCV::VMSLEU_VX:
3921 case RISCV::VMSLE_VX:
3922 case RISCV::VMSGTU_VX:
3923 case RISCV::VMSGT_VX:
3924 // 11.9. Vector Integer Min/Max Instructions
3925 case RISCV::VMINU_VX:
3926 case RISCV::VMIN_VX:
3927 case RISCV::VMAXU_VX:
3928 case RISCV::VMAX_VX:
3929 // 11.10. Vector Single-Width Integer Multiply Instructions
3930 case RISCV::VMUL_VX:
3931 case RISCV::VMULH_VX:
3932 case RISCV::VMULHU_VX:
3933 case RISCV::VMULHSU_VX:
3934 // 11.11. Vector Integer Divide Instructions
3935 case RISCV::VDIVU_VX:
3936 case RISCV::VDIV_VX:
3937 case RISCV::VREMU_VX:
3938 case RISCV::VREM_VX:
3939 // 11.12. Vector Widening Integer Multiply Instructions
3940 case RISCV::VWMUL_VX:
3941 case RISCV::VWMULU_VX:
3942 case RISCV::VWMULSU_VX:
3943 // 11.13. Vector Single-Width Integer Multiply-Add Instructions
3944 case RISCV::VMACC_VX:
3945 case RISCV::VNMSAC_VX:
3946 case RISCV::VMADD_VX:
3947 case RISCV::VNMSUB_VX:
3948 // 11.14. Vector Widening Integer Multiply-Add Instructions
3949 case RISCV::VWMACCU_VX:
3950 case RISCV::VWMACC_VX:
3951 case RISCV::VWMACCSU_VX:
3952 case RISCV::VWMACCUS_VX:
3953 // 11.15. Vector Integer Merge Instructions
3954 case RISCV::VMERGE_VXM:
3955 // 11.16. Vector Integer Move Instructions
3956 case RISCV::VMV_V_X:
3957 // 12.1. Vector Single-Width Saturating Add and Subtract
3958 case RISCV::VSADDU_VX:
3959 case RISCV::VSADD_VX:
3960 case RISCV::VSSUBU_VX:
3961 case RISCV::VSSUB_VX:
3962 // 12.2. Vector Single-Width Averaging Add and Subtract
3963 case RISCV::VAADDU_VX:
3964 case RISCV::VAADD_VX:
3965 case RISCV::VASUBU_VX:
3966 case RISCV::VASUB_VX:
3967 // 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
3968 case RISCV::VSMUL_VX:
3969 // 16.1. Integer Scalar Move Instructions
3970 case RISCV::VMV_S_X:
3971 return 1U << Log2SEW;
3972 }
3973}
3974
3975unsigned RISCV::getRVVMCOpcode(unsigned RVVPseudoOpcode) {
3977 RISCVVPseudosTable::getPseudoInfo(RVVPseudoOpcode);
3978 if (!RVV)
3979 return 0;
3980 return RVV->BaseInstr;
3981}
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)
@ MachineOutlinerDefault
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static ARCCC::CondCode getOppositeBranchCondition(ARCCC::CondCode CC)
Return the inverse of passed condition, i.e. turning COND_E to COND_NE.
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
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.
Module.h This file contains the declarations for the Module class.
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const char LLVMTargetMachineRef TM
#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 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 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 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
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."))
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
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:168
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
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:239
A debug info location.
Definition: DebugLoc.h:33
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:220
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition: Function.h:695
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(unsigned 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:184
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
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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:569
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:346
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
Definition: MachineInstr.h:396
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:566
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:815
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:800
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:782
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:498
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:579
uint32_t getFlags() const
Return the MI flags bitvector.
Definition: MachineInstr.h:391
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.
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
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
std::optional< outliner::OutlinedFunction > getOutliningCandidateInfo(std::vector< outliner::Candidate > &RepeatedSequenceLocs) 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 isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) 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
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
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc) 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
MachineTraceStrategy getMachineCombinerTraceStrategy() const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
virtual outliner::InstrType getOutliningTypeImpl(MachineBasicBlock::iterator &MBBI, unsigned Flags) 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 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:64
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:323
bool erase(PtrType Ptr)
Remove pointer from the set.
Definition: SmallPtrSet.h:361
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:344
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
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:50
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 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 uint8_t TSFlags
Configurable target specific flags.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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 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 bool hasVecPolicyOp(uint64_t TSFlags)
static bool isRVVWideningReduction(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
@ 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)
std::optional< unsigned > getVectorLowDemandedScalarBits(uint16_t Opcode, unsigned Log2SEW)
int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex)
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
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)
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:1722
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 are tuples (A,...
Definition: STLExtras.h:2400
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:280
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:330
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:324
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.
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:244
unsigned getRenamableRegState(bool B)
DWARFExpression::Operation Op
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:2051
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:509
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.
The information necessary to create an outlined function for some class of candidate.