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