1//===-- RISCVRegisterBankInfo.cpp -------------------------------*- 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/// \file
9/// This file implements the targeting of the RegisterBankInfo class for RISC-V.
10/// \todo This should be generated by TableGen.
11//===----------------------------------------------------------------------===//
12
13#include "RISCVRegisterBankInfo.h"
14#include "MCTargetDesc/RISCVMCTargetDesc.h"
15#include "RISCVSubtarget.h"
16#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
17#include "llvm/CodeGen/MachineRegisterInfo.h"
18#include "llvm/CodeGen/RegisterBank.h"
19#include "llvm/CodeGen/RegisterBankInfo.h"
20#include "llvm/CodeGen/TargetRegisterInfo.h"
21#include "llvm/IR/IntrinsicsRISCV.h"
22
23#define GET_TARGET_REGBANK_IMPL
24#include "RISCVGenRegisterBank.inc"
25
26namespace llvm {
27namespace RISCV {
28
29const RegisterBankInfo::PartialMapping PartMappings[] = {
30 // clang-format off
31 {0, 32, GPRBRegBank},
32 {0, 64, GPRBRegBank},
33 {0, 16, FPRBRegBank},
34 {0, 32, FPRBRegBank},
35 {0, 64, FPRBRegBank},
36 {0, 64, VRBRegBank},
37 {0, 128, VRBRegBank},
38 {0, 256, VRBRegBank},
39 {0, 512, VRBRegBank},
40 // clang-format on
41};
42
43enum PartialMappingIdx {
44 PMI_GPRB32 = 0,
45 PMI_GPRB64 = 1,
46 PMI_FPRB16 = 2,
47 PMI_FPRB32 = 3,
48 PMI_FPRB64 = 4,
49 PMI_VRB64 = 5,
50 PMI_VRB128 = 6,
51 PMI_VRB256 = 7,
52 PMI_VRB512 = 8,
53};
54
55const RegisterBankInfo::ValueMapping ValueMappings[] = {
56 // Invalid value mapping.
57 {nullptr, 0},
58 // Maximum 3 GPR operands; 32 bit.
59 {&PartMappings[PMI_GPRB32], 1},
60 {&PartMappings[PMI_GPRB32], 1},
61 {&PartMappings[PMI_GPRB32], 1},
62 // Maximum 3 GPR operands; 64 bit.
63 {&PartMappings[PMI_GPRB64], 1},
64 {&PartMappings[PMI_GPRB64], 1},
65 {&PartMappings[PMI_GPRB64], 1},
66 // Maximum 3 FPR operands; 16 bit.
67 {&PartMappings[PMI_FPRB16], 1},
68 {&PartMappings[PMI_FPRB16], 1},
69 {&PartMappings[PMI_FPRB16], 1},
70 // Maximum 3 FPR operands; 32 bit.
71 {&PartMappings[PMI_FPRB32], 1},
72 {&PartMappings[PMI_FPRB32], 1},
73 {&PartMappings[PMI_FPRB32], 1},
74 // Maximum 3 FPR operands; 64 bit.
75 {&PartMappings[PMI_FPRB64], 1},
76 {&PartMappings[PMI_FPRB64], 1},
77 {&PartMappings[PMI_FPRB64], 1},
78 // Maximum 3 VR LMUL={1, MF2, MF4, MF8} operands.
79 {&PartMappings[PMI_VRB64], 1},
80 {&PartMappings[PMI_VRB64], 1},
81 {&PartMappings[PMI_VRB64], 1},
82 // Maximum 3 VR LMUL=2 operands.
83 {&PartMappings[PMI_VRB128], 1},
84 {&PartMappings[PMI_VRB128], 1},
85 {&PartMappings[PMI_VRB128], 1},
86 // Maximum 3 VR LMUL=4 operands.
87 {&PartMappings[PMI_VRB256], 1},
88 {&PartMappings[PMI_VRB256], 1},
89 {&PartMappings[PMI_VRB256], 1},
90 // Maximum 3 VR LMUL=8 operands.
91 {&PartMappings[PMI_VRB512], 1},
92 {&PartMappings[PMI_VRB512], 1},
93 {&PartMappings[PMI_VRB512], 1},
94};
95
96enum ValueMappingIdx {
97 InvalidIdx = 0,
98 GPRB32Idx = 1,
99 GPRB64Idx = 4,
100 FPRB16Idx = 7,
101 FPRB32Idx = 10,
102 FPRB64Idx = 13,
103 VRB64Idx = 16,
104 VRB128Idx = 19,
105 VRB256Idx = 22,
106 VRB512Idx = 25,
107};
108} // namespace RISCV
109} // namespace llvm
110
111using namespace llvm;
112
113RISCVRegisterBankInfo::RISCVRegisterBankInfo(unsigned HwMode)
114 : RISCVGenRegisterBankInfo(HwMode) {}
115
116const RegisterBank &
117RISCVRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
118 LLT Ty) const {
119 switch (RC.getID()) {
120 // Vector control and status register class
121 case RISCV::VCSRRegClassID:
122 return getRegBank(ID: RISCV::GPRBRegBankID);
123 default:
124 // For all GPR register classes and others, use the default implementation
125 return RISCVGenRegisterBankInfo::getRegBankFromRegClass(RC, Ty);
126 }
127}
128
129static const RegisterBankInfo::ValueMapping *getFPValueMapping(unsigned Size) {
130 unsigned Idx;
131 switch (Size) {
132 default:
133 llvm_unreachable("Unexpected size");
134 case 16:
135 Idx = RISCV::FPRB16Idx;
136 break;
137 case 32:
138 Idx = RISCV::FPRB32Idx;
139 break;
140 case 64:
141 Idx = RISCV::FPRB64Idx;
142 break;
143 }
144 return &RISCV::ValueMappings[Idx];
145}
146
147// TODO: Make this more like AArch64?
148bool RISCVRegisterBankInfo::hasFPConstraints(
149 const MachineInstr &MI, const MachineRegisterInfo &MRI,
150 const TargetRegisterInfo &TRI) const {
151 if (isPreISelGenericFloatingPointOpcode(Opc: MI.getOpcode()))
152 return true;
153
154 // If we have a copy instruction, we could be feeding floating point
155 // instructions.
156 if (MI.getOpcode() != TargetOpcode::COPY)
157 return false;
158
159 return getRegBank(Reg: MI.getOperand(i: 0).getReg(), MRI, TRI) == &RISCV::FPRBRegBank;
160}
161
162bool RISCVRegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
163 const MachineRegisterInfo &MRI,
164 const TargetRegisterInfo &TRI) const {
165 switch (MI.getOpcode()) {
166 case RISCV::G_FCVT_W_RV64:
167 case RISCV::G_FCVT_WU_RV64:
168 case RISCV::G_FCLASS:
169 case TargetOpcode::G_FPTOSI:
170 case TargetOpcode::G_FPTOUI:
171 case TargetOpcode::G_LROUND:
172 case TargetOpcode::G_LLROUND:
173 case TargetOpcode::G_INTRINSIC_LRINT:
174 case TargetOpcode::G_INTRINSIC_LLRINT:
175 case TargetOpcode::G_FCMP:
176 return true;
177 default:
178 break;
179 }
180
181 return hasFPConstraints(MI, MRI, TRI);
182}
183
184bool RISCVRegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
185 const MachineRegisterInfo &MRI,
186 const TargetRegisterInfo &TRI) const {
187 switch (MI.getOpcode()) {
188 case TargetOpcode::G_SITOFP:
189 case TargetOpcode::G_UITOFP:
190 return true;
191 default:
192 break;
193 }
194
195 return hasFPConstraints(MI, MRI, TRI);
196}
197
198bool RISCVRegisterBankInfo::anyUseOnlyUseFP(
199 Register Def, const MachineRegisterInfo &MRI,
200 const TargetRegisterInfo &TRI) const {
201 return any_of(
202 Range: MRI.use_nodbg_instructions(Reg: Def),
203 P: [&](const MachineInstr &UseMI) { return onlyUsesFP(MI: UseMI, MRI, TRI); });
204}
205
206static const RegisterBankInfo::ValueMapping *getVRBValueMapping(unsigned Size) {
207 unsigned Idx;
208
209 if (Size <= 64)
210 Idx = RISCV::VRB64Idx;
211 else if (Size == 128)
212 Idx = RISCV::VRB128Idx;
213 else if (Size == 256)
214 Idx = RISCV::VRB256Idx;
215 else if (Size == 512)
216 Idx = RISCV::VRB512Idx;
217 else
218 llvm::report_fatal_error(reason: "Invalid Size");
219
220 return &RISCV::ValueMappings[Idx];
221}
222
223const RegisterBankInfo::InstructionMapping &
224RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
225 const unsigned Opc = MI.getOpcode();
226
227 // Try the default logic for non-generic instructions that are either copies
228 // or already have some operands assigned to banks.
229 if (!isPreISelGenericOpcode(Opcode: Opc) || Opc == TargetOpcode::G_PHI) {
230 const InstructionMapping &Mapping = getInstrMappingImpl(MI);
231 if (Mapping.isValid())
232 return Mapping;
233 }
234
235 const MachineFunction &MF = *MI.getParent()->getParent();
236 const MachineRegisterInfo &MRI = MF.getRegInfo();
237 const RISCVSubtarget &Subtarget = MF.getSubtarget<RISCVSubtarget>();
238 const TargetRegisterInfo &TRI = *Subtarget.getRegisterInfo();
239
240 unsigned GPRSize = Subtarget.getXLen();
241
242 unsigned NumOperands = MI.getNumOperands();
243 const ValueMapping *GPRValueMapping =
244 &RISCV::ValueMappings[GPRSize == 64 ? RISCV::GPRB64Idx
245 : RISCV::GPRB32Idx];
246
247 switch (Opc) {
248 case TargetOpcode::G_ADD:
249 case TargetOpcode::G_SUB:
250 case TargetOpcode::G_SHL:
251 case TargetOpcode::G_ASHR:
252 case TargetOpcode::G_LSHR:
253 case TargetOpcode::G_AND:
254 case TargetOpcode::G_OR:
255 case TargetOpcode::G_XOR:
256 case TargetOpcode::G_MUL:
257 case TargetOpcode::G_SDIV:
258 case TargetOpcode::G_SREM:
259 case TargetOpcode::G_SMULH:
260 case TargetOpcode::G_SMAX:
261 case TargetOpcode::G_SMIN:
262 case TargetOpcode::G_UDIV:
263 case TargetOpcode::G_UREM:
264 case TargetOpcode::G_UMULH:
265 case TargetOpcode::G_UMAX:
266 case TargetOpcode::G_UMIN:
267 case TargetOpcode::G_PTR_ADD:
268 case TargetOpcode::G_PTRTOINT:
269 case TargetOpcode::G_INTTOPTR:
270 case TargetOpcode::G_FADD:
271 case TargetOpcode::G_FSUB:
272 case TargetOpcode::G_FMUL:
273 case TargetOpcode::G_FDIV:
274 case TargetOpcode::G_FABS:
275 case TargetOpcode::G_FNEG:
276 case TargetOpcode::G_FSQRT:
277 case TargetOpcode::G_FMAXNUM:
278 case TargetOpcode::G_FMINNUM: {
279 LLT Ty = MRI.getType(Reg: MI.getOperand(i: 0).getReg());
280 TypeSize Size = Ty.getSizeInBits();
281
282 const ValueMapping *Mapping;
283 if (Ty.isVector())
284 Mapping = getVRBValueMapping(Size: Size.getKnownMinValue());
285 else if (isPreISelGenericFloatingPointOpcode(Opc))
286 Mapping = getFPValueMapping(Size: Size.getFixedValue());
287 else
288 Mapping = GPRValueMapping;
289
290#ifndef NDEBUG
291 // Make sure all the operands are using similar size and type.
292 for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
293 LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
294 assert(Ty.isVector() == OpTy.isVector() &&
295 "Operand has incompatible type");
296 // Don't check size for GPR.
297 if (OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc))
298 assert(Size == OpTy.getSizeInBits() && "Operand has incompatible size");
299 }
300#endif // End NDEBUG
301
302 return getInstructionMapping(ID: DefaultMappingID, Cost: 1, OperandsMapping: Mapping, NumOperands);
303 }
304 case TargetOpcode::G_SEXTLOAD:
305 case TargetOpcode::G_ZEXTLOAD:
306 return getInstructionMapping(ID: DefaultMappingID, /*Cost=*/1, OperandsMapping: GPRValueMapping,
307 NumOperands);
308 case TargetOpcode::G_IMPLICIT_DEF: {
309 Register Dst = MI.getOperand(i: 0).getReg();
310 LLT DstTy = MRI.getType(Reg: Dst);
311 unsigned DstMinSize = DstTy.getSizeInBits().getKnownMinValue();
312 auto Mapping = GPRValueMapping;
313 // FIXME: May need to do a better job determining when to use FPRB.
314 // For example, the look through COPY case:
315 // %0:_(s32) = G_IMPLICIT_DEF
316 // %1:_(s32) = COPY %0
317 // $f10_d = COPY %1(s32)
318 if (DstTy.isVector())
319 Mapping = getVRBValueMapping(Size: DstMinSize);
320 else if (anyUseOnlyUseFP(Def: Dst, MRI, TRI))
321 Mapping = getFPValueMapping(Size: DstMinSize);
322
323 return getInstructionMapping(ID: DefaultMappingID, /*Cost=*/1, OperandsMapping: Mapping,
324 NumOperands);
325 }
326 }
327
328 SmallVector<const ValueMapping *, 4> OpdsMapping(NumOperands);
329
330 switch (Opc) {
331 case TargetOpcode::G_LOAD: {
332 LLT Ty = MRI.getType(Reg: MI.getOperand(i: 0).getReg());
333 TypeSize Size = Ty.getSizeInBits();
334
335 OpdsMapping[1] = GPRValueMapping;
336
337 if (Ty.isVector()) {
338 OpdsMapping[0] = getVRBValueMapping(Size: Size.getKnownMinValue());
339 break;
340 }
341
342 OpdsMapping[0] = GPRValueMapping;
343
344 // Atomics always use GPR destinations. Don't refine any further.
345 if (cast<GLoad>(Val: MI).isAtomic())
346 break;
347
348 // Use FPR64 for s64 loads on rv32.
349 if (GPRSize == 32 && Size.getFixedValue() == 64) {
350 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
351 OpdsMapping[0] = getFPValueMapping(Size);
352 break;
353 }
354
355 // Check if that load feeds fp instructions.
356 // In that case, we want the default mapping to be on FPR
357 // instead of blind map every scalar to GPR.
358 if (anyUseOnlyUseFP(Def: MI.getOperand(i: 0).getReg(), MRI, TRI)) {
359 // If we have at least one direct use in a FP instruction,
360 // assume this was a floating point load in the IR. If it was
361 // not, we would have had a bitcast before reaching that
362 // instruction.
363 OpdsMapping[0] = getFPValueMapping(Size);
364 break;
365 }
366
367 break;
368 }
369 case TargetOpcode::G_STORE: {
370 LLT Ty = MRI.getType(Reg: MI.getOperand(i: 0).getReg());
371 TypeSize Size = Ty.getSizeInBits();
372
373 OpdsMapping[1] = GPRValueMapping;
374
375 if (Ty.isVector()) {
376 OpdsMapping[0] = getVRBValueMapping(Size: Size.getKnownMinValue());
377 break;
378 }
379
380 OpdsMapping[0] = GPRValueMapping;
381
382 // Atomics always use GPR sources. Don't refine any further.
383 if (cast<GStore>(Val: MI).isAtomic())
384 break;
385
386 // Use FPR64 for s64 stores on rv32.
387 if (GPRSize == 32 && Size.getFixedValue() == 64) {
388 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
389 OpdsMapping[0] = getFPValueMapping(Size: Ty.getSizeInBits());
390 break;
391 }
392
393 MachineInstr *DefMI = MRI.getVRegDef(Reg: MI.getOperand(i: 0).getReg());
394 if (onlyDefinesFP(MI: *DefMI, MRI, TRI))
395 OpdsMapping[0] = getFPValueMapping(Size: Ty.getSizeInBits());
396 break;
397 }
398 case TargetOpcode::G_SELECT: {
399 LLT Ty = MRI.getType(Reg: MI.getOperand(i: 0).getReg());
400
401 if (Ty.isVector()) {
402 auto &Sel = cast<GSelect>(Val: MI);
403 LLT TestTy = MRI.getType(Reg: Sel.getCondReg());
404 assert(TestTy.isVector() && "Unexpected condition argument type");
405 OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] =
406 getVRBValueMapping(Size: Ty.getSizeInBits().getKnownMinValue());
407 OpdsMapping[1] =
408 getVRBValueMapping(Size: TestTy.getSizeInBits().getKnownMinValue());
409 break;
410 }
411
412 // Try to minimize the number of copies. If we have more floating point
413 // constrained values than not, then we'll put everything on FPR. Otherwise,
414 // everything has to be on GPR.
415 unsigned NumFP = 0;
416
417 // Use FPR64 for s64 select on rv32.
418 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
419 NumFP = 3;
420 } else {
421 // Check if the uses of the result always produce floating point values.
422 //
423 // For example:
424 //
425 // %z = G_SELECT %cond %x %y
426 // fpr = G_FOO %z ...
427 if (any_of(Range: MRI.use_nodbg_instructions(Reg: MI.getOperand(i: 0).getReg()),
428 P: [&](const MachineInstr &UseMI) {
429 return onlyUsesFP(MI: UseMI, MRI, TRI);
430 }))
431 ++NumFP;
432
433 // Check if the defs of the source values always produce floating point
434 // values.
435 //
436 // For example:
437 //
438 // %x = G_SOMETHING_ALWAYS_FLOAT %a ...
439 // %z = G_SELECT %cond %x %y
440 //
441 // Also check whether or not the sources have already been decided to be
442 // FPR. Keep track of this.
443 //
444 // This doesn't check the condition, since the condition is always an
445 // integer.
446 for (unsigned Idx = 2; Idx < 4; ++Idx) {
447 Register VReg = MI.getOperand(i: Idx).getReg();
448 MachineInstr *DefMI = MRI.getVRegDef(Reg: VReg);
449 if (getRegBank(Reg: VReg, MRI, TRI) == &RISCV::FPRBRegBank ||
450 onlyDefinesFP(MI: *DefMI, MRI, TRI))
451 ++NumFP;
452 }
453 }
454
455 // Condition operand is always GPR.
456 OpdsMapping[1] = GPRValueMapping;
457
458 const ValueMapping *Mapping = GPRValueMapping;
459 if (NumFP >= 2)
460 Mapping = getFPValueMapping(Size: Ty.getSizeInBits());
461
462 OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping;
463 break;
464 }
465 case RISCV::G_FCVT_W_RV64:
466 case RISCV::G_FCVT_WU_RV64:
467 case TargetOpcode::G_FPTOSI:
468 case TargetOpcode::G_FPTOUI:
469 case TargetOpcode::G_LROUND:
470 case TargetOpcode::G_LLROUND:
471 case TargetOpcode::G_INTRINSIC_LRINT:
472 case TargetOpcode::G_INTRINSIC_LLRINT:
473 case RISCV::G_FCLASS: {
474 LLT Ty = MRI.getType(Reg: MI.getOperand(i: 1).getReg());
475 OpdsMapping[0] = GPRValueMapping;
476 OpdsMapping[1] = getFPValueMapping(Size: Ty.getSizeInBits());
477 break;
478 }
479 case TargetOpcode::G_SITOFP:
480 case TargetOpcode::G_UITOFP: {
481 LLT Ty = MRI.getType(Reg: MI.getOperand(i: 0).getReg());
482 OpdsMapping[0] = getFPValueMapping(Size: Ty.getSizeInBits());
483 OpdsMapping[1] = GPRValueMapping;
484 break;
485 }
486 case TargetOpcode::G_FCMP: {
487 LLT Ty = MRI.getType(Reg: MI.getOperand(i: 2).getReg());
488
489 unsigned Size = Ty.getSizeInBits();
490
491 OpdsMapping[0] = GPRValueMapping;
492 OpdsMapping[2] = OpdsMapping[3] = getFPValueMapping(Size);
493 break;
494 }
495 case TargetOpcode::G_MERGE_VALUES: {
496 // Use FPR64 for s64 merge on rv32.
497 LLT Ty = MRI.getType(Reg: MI.getOperand(i: 0).getReg());
498 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
499 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
500 OpdsMapping[0] = getFPValueMapping(Size: Ty.getSizeInBits());
501 OpdsMapping[1] = GPRValueMapping;
502 OpdsMapping[2] = GPRValueMapping;
503 }
504 break;
505 }
506 case TargetOpcode::G_UNMERGE_VALUES: {
507 // Use FPR64 for s64 unmerge on rv32.
508 LLT Ty = MRI.getType(Reg: MI.getOperand(i: 2).getReg());
509 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
510 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
511 OpdsMapping[0] = GPRValueMapping;
512 OpdsMapping[1] = GPRValueMapping;
513 OpdsMapping[2] = getFPValueMapping(Size: Ty.getSizeInBits());
514 }
515 break;
516 }
517 case TargetOpcode::G_SPLAT_VECTOR: {
518 OpdsMapping[0] = getVRBValueMapping(Size: MRI.getType(Reg: MI.getOperand(i: 0).getReg())
519 .getSizeInBits()
520 .getKnownMinValue());
521
522 LLT ScalarTy = MRI.getType(Reg: MI.getOperand(i: 1).getReg());
523 MachineInstr *DefMI = MRI.getVRegDef(Reg: MI.getOperand(i: 1).getReg());
524 if ((GPRSize == 32 && ScalarTy.getSizeInBits() == 64) ||
525 onlyDefinesFP(MI: *DefMI, MRI, TRI)) {
526 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
527 OpdsMapping[1] = getFPValueMapping(Size: ScalarTy.getSizeInBits());
528 } else
529 OpdsMapping[1] = GPRValueMapping;
530 break;
531 }
532 case TargetOpcode::G_INTRINSIC: {
533 Intrinsic::ID IntrinsicID = cast<GIntrinsic>(Val: MI).getIntrinsicID();
534
535 if (const RISCVVIntrinsicsTable::RISCVVIntrinsicInfo *II =
536 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) {
537 unsigned ScalarIdx = -1;
538 if (II->hasScalarOperand()) {
539 ScalarIdx = II->ScalarOperand + 2;
540 }
541 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
542 const MachineOperand &MO = MI.getOperand(i: Idx);
543 if (!MO.isReg())
544 continue;
545 LLT Ty = MRI.getType(Reg: MO.getReg());
546 if (Ty.isVector()) {
547 OpdsMapping[Idx] =
548 getVRBValueMapping(Size: Ty.getSizeInBits().getKnownMinValue());
549 } else if (II->IsFPIntrinsic && ScalarIdx == Idx) {
550 // Chose the right FPR for scalar operand of RVV intrinsics.
551 OpdsMapping[Idx] = getFPValueMapping(Size: Ty.getSizeInBits());
552 } else {
553 OpdsMapping[Idx] = GPRValueMapping;
554 }
555 }
556 }
557
558 if (IntrinsicID == Intrinsic::riscv_vsetvli ||
559 IntrinsicID == Intrinsic::riscv_vsetvlimax) {
560 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
561 const MachineOperand &MO = MI.getOperand(i: Idx);
562 if (!MO.isReg())
563 continue;
564 OpdsMapping[Idx] = GPRValueMapping;
565 }
566 }
567 break;
568 }
569 default:
570 // By default map all scalars to GPR.
571 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
572 auto &MO = MI.getOperand(i: Idx);
573 if (!MO.isReg() || !MO.getReg())
574 continue;
575 LLT Ty = MRI.getType(Reg: MO.getReg());
576 if (!Ty.isValid())
577 continue;
578
579 if (Ty.isVector())
580 OpdsMapping[Idx] =
581 getVRBValueMapping(Size: Ty.getSizeInBits().getKnownMinValue());
582 else if (isPreISelGenericFloatingPointOpcode(Opc))
583 OpdsMapping[Idx] = getFPValueMapping(Size: Ty.getSizeInBits());
584 else
585 OpdsMapping[Idx] = GPRValueMapping;
586 }
587 break;
588 }
589
590 return getInstructionMapping(ID: DefaultMappingID, /*Cost=*/1,
591 OperandsMapping: getOperandsMapping(OpdsMapping), NumOperands);
592}
593