1 //===- AArch64RegisterBankInfo.cpp ----------------------------------------===//
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
10 /// AArch64.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
13 
14 #include "AArch64RegisterBankInfo.h"
15 #include "AArch64RegisterInfo.h"
16 #include "MCTargetDesc/AArch64MCTargetDesc.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
20 #include "llvm/CodeGen/GlobalISel/Utils.h"
21 #include "llvm/CodeGen/LowLevelTypeUtils.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineInstr.h"
24 #include "llvm/CodeGen/MachineOperand.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/RegisterBank.h"
27 #include "llvm/CodeGen/RegisterBankInfo.h"
28 #include "llvm/CodeGen/TargetOpcodes.h"
29 #include "llvm/CodeGen/TargetRegisterInfo.h"
30 #include "llvm/CodeGen/TargetSubtargetInfo.h"
31 #include "llvm/IR/IntrinsicsAArch64.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include <algorithm>
34 #include <cassert>
35 
36 #define GET_TARGET_REGBANK_IMPL
37 #include "AArch64GenRegisterBank.inc"
38 
39 // This file will be TableGen'ed at some point.
40 #include "AArch64GenRegisterBankInfo.def"
41 
42 using namespace llvm;
43 
44 AArch64RegisterBankInfo::AArch64RegisterBankInfo(
45     const TargetRegisterInfo &TRI) {
46   static llvm::once_flag InitializeRegisterBankFlag;
47 
48   static auto InitializeRegisterBankOnce = [&]() {
49     // We have only one set of register banks, whatever the subtarget
50     // is. Therefore, the initialization of the RegBanks table should be
51     // done only once. Indeed the table of all register banks
52     // (AArch64::RegBanks) is unique in the compiler. At some point, it
53     // will get tablegen'ed and the whole constructor becomes empty.
54 
55     const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID);
56     (void)RBGPR;
57     assert(&AArch64::GPRRegBank == &RBGPR &&
58            "The order in RegBanks is messed up");
59 
60     const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID);
61     (void)RBFPR;
62     assert(&AArch64::FPRRegBank == &RBFPR &&
63            "The order in RegBanks is messed up");
64 
65     const RegisterBank &RBCCR = getRegBank(AArch64::CCRegBankID);
66     (void)RBCCR;
67     assert(&AArch64::CCRegBank == &RBCCR &&
68            "The order in RegBanks is messed up");
69 
70     // The GPR register bank is fully defined by all the registers in
71     // GR64all + its subclasses.
72     assert(RBGPR.covers(*TRI.getRegClass(AArch64::GPR32RegClassID)) &&
73            "Subclass not added?");
74     assert(getMaximumSize(RBGPR.getID()) == 128 &&
75            "GPRs should hold up to 128-bit");
76 
77     // The FPR register bank is fully defined by all the registers in
78     // GR64all + its subclasses.
79     assert(RBFPR.covers(*TRI.getRegClass(AArch64::QQRegClassID)) &&
80            "Subclass not added?");
81     assert(RBFPR.covers(*TRI.getRegClass(AArch64::FPR64RegClassID)) &&
82            "Subclass not added?");
83     assert(getMaximumSize(RBFPR.getID()) == 512 &&
84            "FPRs should hold up to 512-bit via QQQQ sequence");
85 
86     assert(RBCCR.covers(*TRI.getRegClass(AArch64::CCRRegClassID)) &&
87            "Class not added?");
88     assert(getMaximumSize(RBCCR.getID()) == 32 &&
89            "CCR should hold up to 32-bit");
90 
91     // Check that the TableGen'ed like file is in sync we our expectations.
92     // First, the Idx.
93     assert(checkPartialMappingIdx(PMI_FirstGPR, PMI_LastGPR,
94                                   {PMI_GPR32, PMI_GPR64, PMI_GPR128}) &&
95            "PartialMappingIdx's are incorrectly ordered");
96     assert(checkPartialMappingIdx(PMI_FirstFPR, PMI_LastFPR,
97                                   {PMI_FPR16, PMI_FPR32, PMI_FPR64, PMI_FPR128,
98                                    PMI_FPR256, PMI_FPR512}) &&
99            "PartialMappingIdx's are incorrectly ordered");
100 // Now, the content.
101 // Check partial mapping.
102 #define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB)                      \
103   do {                                                                         \
104     assert(                                                                    \
105         checkPartialMap(PartialMappingIdx::Idx, ValStartIdx, ValLength, RB) && \
106         #Idx " is incorrectly initialized");                                   \
107   } while (false)
108 
109     CHECK_PARTIALMAP(PMI_GPR32, 0, 32, RBGPR);
110     CHECK_PARTIALMAP(PMI_GPR64, 0, 64, RBGPR);
111     CHECK_PARTIALMAP(PMI_GPR128, 0, 128, RBGPR);
112     CHECK_PARTIALMAP(PMI_FPR16, 0, 16, RBFPR);
113     CHECK_PARTIALMAP(PMI_FPR32, 0, 32, RBFPR);
114     CHECK_PARTIALMAP(PMI_FPR64, 0, 64, RBFPR);
115     CHECK_PARTIALMAP(PMI_FPR128, 0, 128, RBFPR);
116     CHECK_PARTIALMAP(PMI_FPR256, 0, 256, RBFPR);
117     CHECK_PARTIALMAP(PMI_FPR512, 0, 512, RBFPR);
118 
119 // Check value mapping.
120 #define CHECK_VALUEMAP_IMPL(RBName, Size, Offset)                              \
121   do {                                                                         \
122     assert(checkValueMapImpl(PartialMappingIdx::PMI_##RBName##Size,            \
123                              PartialMappingIdx::PMI_First##RBName, Size,       \
124                              Offset) &&                                        \
125            #RBName #Size " " #Offset " is incorrectly initialized");           \
126   } while (false)
127 
128 #define CHECK_VALUEMAP(RBName, Size) CHECK_VALUEMAP_IMPL(RBName, Size, 0)
129 
130     CHECK_VALUEMAP(GPR, 32);
131     CHECK_VALUEMAP(GPR, 64);
132     CHECK_VALUEMAP(GPR, 128);
133     CHECK_VALUEMAP(FPR, 16);
134     CHECK_VALUEMAP(FPR, 32);
135     CHECK_VALUEMAP(FPR, 64);
136     CHECK_VALUEMAP(FPR, 128);
137     CHECK_VALUEMAP(FPR, 256);
138     CHECK_VALUEMAP(FPR, 512);
139 
140 // Check the value mapping for 3-operands instructions where all the operands
141 // map to the same value mapping.
142 #define CHECK_VALUEMAP_3OPS(RBName, Size)                                      \
143   do {                                                                         \
144     CHECK_VALUEMAP_IMPL(RBName, Size, 0);                                      \
145     CHECK_VALUEMAP_IMPL(RBName, Size, 1);                                      \
146     CHECK_VALUEMAP_IMPL(RBName, Size, 2);                                      \
147   } while (false)
148 
149     CHECK_VALUEMAP_3OPS(GPR, 32);
150     CHECK_VALUEMAP_3OPS(GPR, 64);
151     CHECK_VALUEMAP_3OPS(GPR, 128);
152     CHECK_VALUEMAP_3OPS(FPR, 32);
153     CHECK_VALUEMAP_3OPS(FPR, 64);
154     CHECK_VALUEMAP_3OPS(FPR, 128);
155     CHECK_VALUEMAP_3OPS(FPR, 256);
156     CHECK_VALUEMAP_3OPS(FPR, 512);
157 
158 #define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size)                 \
159   do {                                                                         \
160     unsigned PartialMapDstIdx = PMI_##RBNameDst##Size - PMI_Min;               \
161     unsigned PartialMapSrcIdx = PMI_##RBNameSrc##Size - PMI_Min;               \
162     (void)PartialMapDstIdx;                                                    \
163     (void)PartialMapSrcIdx;                                                    \
164     const ValueMapping *Map = getCopyMapping(                                  \
165         AArch64::RBNameDst##RegBankID, AArch64::RBNameSrc##RegBankID, Size);  \
166     (void)Map;                                                                 \
167     assert(Map[0].BreakDown ==                                                 \
168                &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] &&  \
169            Map[0].NumBreakDowns == 1 && #RBNameDst #Size                       \
170            " Dst is incorrectly initialized");                                 \
171     assert(Map[1].BreakDown ==                                                 \
172                &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] &&  \
173            Map[1].NumBreakDowns == 1 && #RBNameSrc #Size                       \
174            " Src is incorrectly initialized");                                 \
175                                                                                \
176   } while (false)
177 
178     CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 32);
179     CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 32);
180     CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 64);
181     CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 64);
182     CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 32);
183     CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 32);
184     CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 64);
185     CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 64);
186 
187 #define CHECK_VALUEMAP_FPEXT(DstSize, SrcSize)                                 \
188   do {                                                                         \
189     unsigned PartialMapDstIdx = PMI_FPR##DstSize - PMI_Min;                    \
190     unsigned PartialMapSrcIdx = PMI_FPR##SrcSize - PMI_Min;                    \
191     (void)PartialMapDstIdx;                                                    \
192     (void)PartialMapSrcIdx;                                                    \
193     const ValueMapping *Map = getFPExtMapping(DstSize, SrcSize);               \
194     (void)Map;                                                                 \
195     assert(Map[0].BreakDown ==                                                 \
196                &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] &&  \
197            Map[0].NumBreakDowns == 1 && "FPR" #DstSize                         \
198                                         " Dst is incorrectly initialized");    \
199     assert(Map[1].BreakDown ==                                                 \
200                &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] &&  \
201            Map[1].NumBreakDowns == 1 && "FPR" #SrcSize                         \
202                                         " Src is incorrectly initialized");    \
203                                                                                \
204   } while (false)
205 
206     CHECK_VALUEMAP_FPEXT(32, 16);
207     CHECK_VALUEMAP_FPEXT(64, 16);
208     CHECK_VALUEMAP_FPEXT(64, 32);
209     CHECK_VALUEMAP_FPEXT(128, 64);
210 
211     assert(verify(TRI) && "Invalid register bank information");
212   };
213 
214   llvm::call_once(InitializeRegisterBankFlag, InitializeRegisterBankOnce);
215 }
216 
217 unsigned AArch64RegisterBankInfo::copyCost(const RegisterBank &A,
218                                            const RegisterBank &B,
219                                            unsigned Size) const {
220   // What do we do with different size?
221   // copy are same size.
222   // Will introduce other hooks for different size:
223   // * extract cost.
224   // * build_sequence cost.
225 
226   // Copy from (resp. to) GPR to (resp. from) FPR involves FMOV.
227   // FIXME: This should be deduced from the scheduling model.
228   if (&A == &AArch64::GPRRegBank && &B == &AArch64::FPRRegBank)
229     // FMOVXDr or FMOVWSr.
230     return 5;
231   if (&A == &AArch64::FPRRegBank && &B == &AArch64::GPRRegBank)
232     // FMOVDXr or FMOVSWr.
233     return 4;
234 
235   return RegisterBankInfo::copyCost(A, B, Size);
236 }
237 
238 const RegisterBank &
239 AArch64RegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
240                                                 LLT) const {
241   switch (RC.getID()) {
242   case AArch64::FPR8RegClassID:
243   case AArch64::FPR16RegClassID:
244   case AArch64::FPR16_loRegClassID:
245   case AArch64::FPR32_with_hsub_in_FPR16_loRegClassID:
246   case AArch64::FPR32RegClassID:
247   case AArch64::FPR64RegClassID:
248   case AArch64::FPR64_loRegClassID:
249   case AArch64::FPR128RegClassID:
250   case AArch64::FPR128_loRegClassID:
251   case AArch64::DDRegClassID:
252   case AArch64::DDDRegClassID:
253   case AArch64::DDDDRegClassID:
254   case AArch64::QQRegClassID:
255   case AArch64::QQQRegClassID:
256   case AArch64::QQQQRegClassID:
257     return getRegBank(AArch64::FPRRegBankID);
258   case AArch64::GPR32commonRegClassID:
259   case AArch64::GPR32RegClassID:
260   case AArch64::GPR32spRegClassID:
261   case AArch64::GPR32sponlyRegClassID:
262   case AArch64::GPR32argRegClassID:
263   case AArch64::GPR32allRegClassID:
264   case AArch64::GPR64commonRegClassID:
265   case AArch64::GPR64RegClassID:
266   case AArch64::GPR64spRegClassID:
267   case AArch64::GPR64sponlyRegClassID:
268   case AArch64::GPR64argRegClassID:
269   case AArch64::GPR64allRegClassID:
270   case AArch64::GPR64noipRegClassID:
271   case AArch64::GPR64common_and_GPR64noipRegClassID:
272   case AArch64::GPR64noip_and_tcGPR64RegClassID:
273   case AArch64::tcGPR64RegClassID:
274   case AArch64::rtcGPR64RegClassID:
275   case AArch64::WSeqPairsClassRegClassID:
276   case AArch64::XSeqPairsClassRegClassID:
277   case AArch64::MatrixIndexGPR32_8_11RegClassID:
278   case AArch64::MatrixIndexGPR32_12_15RegClassID:
279   case AArch64::GPR64_with_sub_32_in_MatrixIndexGPR32_8_11RegClassID:
280   case AArch64::GPR64_with_sub_32_in_MatrixIndexGPR32_12_15RegClassID:
281     return getRegBank(AArch64::GPRRegBankID);
282   case AArch64::CCRRegClassID:
283     return getRegBank(AArch64::CCRegBankID);
284   default:
285     llvm_unreachable("Register class not supported");
286   }
287 }
288 
289 RegisterBankInfo::InstructionMappings
290 AArch64RegisterBankInfo::getInstrAlternativeMappings(
291     const MachineInstr &MI) const {
292   const MachineFunction &MF = *MI.getParent()->getParent();
293   const TargetSubtargetInfo &STI = MF.getSubtarget();
294   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
295   const MachineRegisterInfo &MRI = MF.getRegInfo();
296 
297   switch (MI.getOpcode()) {
298   case TargetOpcode::G_OR: {
299     // 32 and 64-bit or can be mapped on either FPR or
300     // GPR for the same cost.
301     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
302     if (Size != 32 && Size != 64)
303       break;
304 
305     // If the instruction has any implicit-defs or uses,
306     // do not mess with it.
307     if (MI.getNumOperands() != 3)
308       break;
309     InstructionMappings AltMappings;
310     const InstructionMapping &GPRMapping = getInstructionMapping(
311         /*ID*/ 1, /*Cost*/ 1, getValueMapping(PMI_FirstGPR, Size),
312         /*NumOperands*/ 3);
313     const InstructionMapping &FPRMapping = getInstructionMapping(
314         /*ID*/ 2, /*Cost*/ 1, getValueMapping(PMI_FirstFPR, Size),
315         /*NumOperands*/ 3);
316 
317     AltMappings.push_back(&GPRMapping);
318     AltMappings.push_back(&FPRMapping);
319     return AltMappings;
320   }
321   case TargetOpcode::G_BITCAST: {
322     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
323     if (Size != 32 && Size != 64)
324       break;
325 
326     // If the instruction has any implicit-defs or uses,
327     // do not mess with it.
328     if (MI.getNumOperands() != 2)
329       break;
330 
331     InstructionMappings AltMappings;
332     const InstructionMapping &GPRMapping = getInstructionMapping(
333         /*ID*/ 1, /*Cost*/ 1,
334         getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size),
335         /*NumOperands*/ 2);
336     const InstructionMapping &FPRMapping = getInstructionMapping(
337         /*ID*/ 2, /*Cost*/ 1,
338         getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size),
339         /*NumOperands*/ 2);
340     const InstructionMapping &GPRToFPRMapping = getInstructionMapping(
341         /*ID*/ 3,
342         /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
343         getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size),
344         /*NumOperands*/ 2);
345     const InstructionMapping &FPRToGPRMapping = getInstructionMapping(
346         /*ID*/ 3,
347         /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
348         getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size),
349         /*NumOperands*/ 2);
350 
351     AltMappings.push_back(&GPRMapping);
352     AltMappings.push_back(&FPRMapping);
353     AltMappings.push_back(&GPRToFPRMapping);
354     AltMappings.push_back(&FPRToGPRMapping);
355     return AltMappings;
356   }
357   case TargetOpcode::G_LOAD: {
358     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
359     if (Size != 64)
360       break;
361 
362     // If the instruction has any implicit-defs or uses,
363     // do not mess with it.
364     if (MI.getNumOperands() != 2)
365       break;
366 
367     InstructionMappings AltMappings;
368     const InstructionMapping &GPRMapping = getInstructionMapping(
369         /*ID*/ 1, /*Cost*/ 1,
370         getOperandsMapping({getValueMapping(PMI_FirstGPR, Size),
371                             // Addresses are GPR 64-bit.
372                             getValueMapping(PMI_FirstGPR, 64)}),
373         /*NumOperands*/ 2);
374     const InstructionMapping &FPRMapping = getInstructionMapping(
375         /*ID*/ 2, /*Cost*/ 1,
376         getOperandsMapping({getValueMapping(PMI_FirstFPR, Size),
377                             // Addresses are GPR 64-bit.
378                             getValueMapping(PMI_FirstGPR, 64)}),
379         /*NumOperands*/ 2);
380 
381     AltMappings.push_back(&GPRMapping);
382     AltMappings.push_back(&FPRMapping);
383     return AltMappings;
384   }
385   default:
386     break;
387   }
388   return RegisterBankInfo::getInstrAlternativeMappings(MI);
389 }
390 
391 void AArch64RegisterBankInfo::applyMappingImpl(
392     const OperandsMapper &OpdMapper) const {
393   switch (OpdMapper.getMI().getOpcode()) {
394   case TargetOpcode::G_OR:
395   case TargetOpcode::G_BITCAST:
396   case TargetOpcode::G_LOAD:
397     // Those ID must match getInstrAlternativeMappings.
398     assert((OpdMapper.getInstrMapping().getID() >= 1 &&
399             OpdMapper.getInstrMapping().getID() <= 4) &&
400            "Don't know how to handle that ID");
401     return applyDefaultMapping(OpdMapper);
402   default:
403     llvm_unreachable("Don't know how to handle that operation");
404   }
405 }
406 
407 /// Returns whether opcode \p Opc is a pre-isel generic floating-point opcode,
408 /// having only floating-point operands.
409 static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) {
410   switch (Opc) {
411   case TargetOpcode::G_FADD:
412   case TargetOpcode::G_FSUB:
413   case TargetOpcode::G_FMUL:
414   case TargetOpcode::G_FMA:
415   case TargetOpcode::G_FDIV:
416   case TargetOpcode::G_FCONSTANT:
417   case TargetOpcode::G_FPEXT:
418   case TargetOpcode::G_FPTRUNC:
419   case TargetOpcode::G_FCEIL:
420   case TargetOpcode::G_FFLOOR:
421   case TargetOpcode::G_FNEARBYINT:
422   case TargetOpcode::G_FNEG:
423   case TargetOpcode::G_FCOS:
424   case TargetOpcode::G_FSIN:
425   case TargetOpcode::G_FLOG10:
426   case TargetOpcode::G_FLOG:
427   case TargetOpcode::G_FLOG2:
428   case TargetOpcode::G_FSQRT:
429   case TargetOpcode::G_FABS:
430   case TargetOpcode::G_FEXP:
431   case TargetOpcode::G_FRINT:
432   case TargetOpcode::G_INTRINSIC_TRUNC:
433   case TargetOpcode::G_INTRINSIC_ROUND:
434   case TargetOpcode::G_FMAXNUM:
435   case TargetOpcode::G_FMINNUM:
436   case TargetOpcode::G_FMAXIMUM:
437   case TargetOpcode::G_FMINIMUM:
438     return true;
439   }
440   return false;
441 }
442 
443 const RegisterBankInfo::InstructionMapping &
444 AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
445     const MachineInstr &MI) const {
446   const unsigned Opc = MI.getOpcode();
447   const MachineFunction &MF = *MI.getParent()->getParent();
448   const MachineRegisterInfo &MRI = MF.getRegInfo();
449 
450   unsigned NumOperands = MI.getNumOperands();
451   assert(NumOperands <= 3 &&
452          "This code is for instructions with 3 or less operands");
453 
454   LLT Ty = MRI.getType(MI.getOperand(0).getReg());
455   unsigned Size = Ty.getSizeInBits();
456   bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
457 
458   PartialMappingIdx RBIdx = IsFPR ? PMI_FirstFPR : PMI_FirstGPR;
459 
460 #ifndef NDEBUG
461   // Make sure all the operands are using similar size and type.
462   // Should probably be checked by the machine verifier.
463   // This code won't catch cases where the number of lanes is
464   // different between the operands.
465   // If we want to go to that level of details, it is probably
466   // best to check that the types are the same, period.
467   // Currently, we just check that the register banks are the same
468   // for each types.
469   for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
470     LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
471     assert(
472         AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(
473             RBIdx, OpTy.getSizeInBits()) ==
474             AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(RBIdx, Size) &&
475         "Operand has incompatible size");
476     bool OpIsFPR = OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
477     (void)OpIsFPR;
478     assert(IsFPR == OpIsFPR && "Operand has incompatible type");
479   }
480 #endif // End NDEBUG.
481 
482   return getInstructionMapping(DefaultMappingID, 1,
483                                getValueMapping(RBIdx, Size), NumOperands);
484 }
485 
486 /// \returns true if a given intrinsic only uses and defines FPRs.
487 static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
488                           const MachineInstr &MI) {
489   assert(MI.getOpcode() == TargetOpcode::G_INTRINSIC);
490   // TODO: Add more intrinsics.
491   switch (MI.getIntrinsicID()) {
492   default:
493     return false;
494   case Intrinsic::aarch64_neon_uaddlv:
495   case Intrinsic::aarch64_neon_uaddv:
496   case Intrinsic::aarch64_neon_umaxv:
497   case Intrinsic::aarch64_neon_uminv:
498   case Intrinsic::aarch64_neon_fmaxv:
499   case Intrinsic::aarch64_neon_fminv:
500   case Intrinsic::aarch64_neon_fmaxnmv:
501   case Intrinsic::aarch64_neon_fminnmv:
502     return true;
503   case Intrinsic::aarch64_neon_saddlv: {
504     const LLT SrcTy = MRI.getType(MI.getOperand(2).getReg());
505     return SrcTy.getElementType().getSizeInBits() >= 16 &&
506            SrcTy.getElementCount().getFixedValue() >= 4;
507   }
508   case Intrinsic::aarch64_neon_saddv:
509   case Intrinsic::aarch64_neon_smaxv:
510   case Intrinsic::aarch64_neon_sminv: {
511     const LLT SrcTy = MRI.getType(MI.getOperand(2).getReg());
512     return SrcTy.getElementType().getSizeInBits() >= 32 &&
513            SrcTy.getElementCount().getFixedValue() >= 2;
514   }
515   }
516 }
517 
518 bool AArch64RegisterBankInfo::hasFPConstraints(const MachineInstr &MI,
519                                                const MachineRegisterInfo &MRI,
520                                                const TargetRegisterInfo &TRI,
521                                                unsigned Depth) const {
522   unsigned Op = MI.getOpcode();
523   if (Op == TargetOpcode::G_INTRINSIC && isFPIntrinsic(MRI, MI))
524     return true;
525 
526   // Do we have an explicit floating point instruction?
527   if (isPreISelGenericFloatingPointOpcode(Op))
528     return true;
529 
530   // No. Check if we have a copy-like instruction. If we do, then we could
531   // still be fed by floating point instructions.
532   if (Op != TargetOpcode::COPY && !MI.isPHI() &&
533       !isPreISelGenericOptimizationHint(Op))
534     return false;
535 
536   // Check if we already know the register bank.
537   auto *RB = getRegBank(MI.getOperand(0).getReg(), MRI, TRI);
538   if (RB == &AArch64::FPRRegBank)
539     return true;
540   if (RB == &AArch64::GPRRegBank)
541     return false;
542 
543   // We don't know anything.
544   //
545   // If we have a phi, we may be able to infer that it will be assigned a FPR
546   // based off of its inputs.
547   if (!MI.isPHI() || Depth > MaxFPRSearchDepth)
548     return false;
549 
550   return any_of(MI.explicit_uses(), [&](const MachineOperand &Op) {
551     return Op.isReg() &&
552            onlyDefinesFP(*MRI.getVRegDef(Op.getReg()), MRI, TRI, Depth + 1);
553   });
554 }
555 
556 bool AArch64RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
557                                          const MachineRegisterInfo &MRI,
558                                          const TargetRegisterInfo &TRI,
559                                          unsigned Depth) const {
560   switch (MI.getOpcode()) {
561   case TargetOpcode::G_FPTOSI:
562   case TargetOpcode::G_FPTOUI:
563   case TargetOpcode::G_FCMP:
564   case TargetOpcode::G_LROUND:
565   case TargetOpcode::G_LLROUND:
566     return true;
567   default:
568     break;
569   }
570   return hasFPConstraints(MI, MRI, TRI, Depth);
571 }
572 
573 bool AArch64RegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
574                                             const MachineRegisterInfo &MRI,
575                                             const TargetRegisterInfo &TRI,
576                                             unsigned Depth) const {
577   switch (MI.getOpcode()) {
578   case AArch64::G_DUP:
579   case TargetOpcode::G_SITOFP:
580   case TargetOpcode::G_UITOFP:
581   case TargetOpcode::G_EXTRACT_VECTOR_ELT:
582   case TargetOpcode::G_INSERT_VECTOR_ELT:
583   case TargetOpcode::G_BUILD_VECTOR:
584   case TargetOpcode::G_BUILD_VECTOR_TRUNC:
585     return true;
586   default:
587     break;
588   }
589   return hasFPConstraints(MI, MRI, TRI, Depth);
590 }
591 
592 const RegisterBankInfo::InstructionMapping &
593 AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
594   const unsigned Opc = MI.getOpcode();
595 
596   // Try the default logic for non-generic instructions that are either copies
597   // or already have some operands assigned to banks.
598   if ((Opc != TargetOpcode::COPY && !isPreISelGenericOpcode(Opc)) ||
599       Opc == TargetOpcode::G_PHI) {
600     const RegisterBankInfo::InstructionMapping &Mapping =
601         getInstrMappingImpl(MI);
602     if (Mapping.isValid())
603       return Mapping;
604   }
605 
606   const MachineFunction &MF = *MI.getParent()->getParent();
607   const MachineRegisterInfo &MRI = MF.getRegInfo();
608   const TargetSubtargetInfo &STI = MF.getSubtarget();
609   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
610 
611   switch (Opc) {
612     // G_{F|S|U}REM are not listed because they are not legal.
613     // Arithmetic ops.
614   case TargetOpcode::G_ADD:
615   case TargetOpcode::G_SUB:
616   case TargetOpcode::G_PTR_ADD:
617   case TargetOpcode::G_MUL:
618   case TargetOpcode::G_SDIV:
619   case TargetOpcode::G_UDIV:
620     // Bitwise ops.
621   case TargetOpcode::G_AND:
622   case TargetOpcode::G_OR:
623   case TargetOpcode::G_XOR:
624     // Floating point ops.
625   case TargetOpcode::G_FADD:
626   case TargetOpcode::G_FSUB:
627   case TargetOpcode::G_FMUL:
628   case TargetOpcode::G_FDIV:
629   case TargetOpcode::G_FMAXIMUM:
630   case TargetOpcode::G_FMINIMUM:
631     return getSameKindOfOperandsMapping(MI);
632   case TargetOpcode::G_FPEXT: {
633     LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
634     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
635     return getInstructionMapping(
636         DefaultMappingID, /*Cost*/ 1,
637         getFPExtMapping(DstTy.getSizeInBits(), SrcTy.getSizeInBits()),
638         /*NumOperands*/ 2);
639   }
640     // Shifts.
641   case TargetOpcode::G_SHL:
642   case TargetOpcode::G_LSHR:
643   case TargetOpcode::G_ASHR: {
644     LLT ShiftAmtTy = MRI.getType(MI.getOperand(2).getReg());
645     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
646     if (ShiftAmtTy.getSizeInBits() == 64 && SrcTy.getSizeInBits() == 32)
647       return getInstructionMapping(DefaultMappingID, 1,
648                                    &ValMappings[Shift64Imm], 3);
649     return getSameKindOfOperandsMapping(MI);
650   }
651   case TargetOpcode::COPY: {
652     Register DstReg = MI.getOperand(0).getReg();
653     Register SrcReg = MI.getOperand(1).getReg();
654     // Check if one of the register is not a generic register.
655     if ((DstReg.isPhysical() || !MRI.getType(DstReg).isValid()) ||
656         (SrcReg.isPhysical() || !MRI.getType(SrcReg).isValid())) {
657       const RegisterBank *DstRB = getRegBank(DstReg, MRI, TRI);
658       const RegisterBank *SrcRB = getRegBank(SrcReg, MRI, TRI);
659       if (!DstRB)
660         DstRB = SrcRB;
661       else if (!SrcRB)
662         SrcRB = DstRB;
663       // If both RB are null that means both registers are generic.
664       // We shouldn't be here.
665       assert(DstRB && SrcRB && "Both RegBank were nullptr");
666       unsigned Size = getSizeInBits(DstReg, MRI, TRI);
667       return getInstructionMapping(
668           DefaultMappingID, copyCost(*DstRB, *SrcRB, Size),
669           getCopyMapping(DstRB->getID(), SrcRB->getID(), Size),
670           // We only care about the mapping of the destination.
671           /*NumOperands*/ 1);
672     }
673     // Both registers are generic, use G_BITCAST.
674     [[fallthrough]];
675   }
676   case TargetOpcode::G_BITCAST: {
677     LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
678     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
679     unsigned Size = DstTy.getSizeInBits();
680     bool DstIsGPR = !DstTy.isVector() && DstTy.getSizeInBits() <= 64;
681     bool SrcIsGPR = !SrcTy.isVector() && SrcTy.getSizeInBits() <= 64;
682     const RegisterBank &DstRB =
683         DstIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
684     const RegisterBank &SrcRB =
685         SrcIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
686     return getInstructionMapping(
687         DefaultMappingID, copyCost(DstRB, SrcRB, Size),
688         getCopyMapping(DstRB.getID(), SrcRB.getID(), Size),
689         // We only care about the mapping of the destination for COPY.
690         /*NumOperands*/ Opc == TargetOpcode::G_BITCAST ? 2 : 1);
691   }
692   default:
693     break;
694   }
695 
696   unsigned NumOperands = MI.getNumOperands();
697 
698   // Track the size and bank of each register.  We don't do partial mappings.
699   SmallVector<unsigned, 4> OpSize(NumOperands);
700   SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
701   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
702     auto &MO = MI.getOperand(Idx);
703     if (!MO.isReg() || !MO.getReg())
704       continue;
705 
706     LLT Ty = MRI.getType(MO.getReg());
707     if (!Ty.isValid())
708       continue;
709     OpSize[Idx] = Ty.getSizeInBits();
710 
711     // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs.
712     // For floating-point instructions, scalars go in FPRs.
713     if (Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc) ||
714         Ty.getSizeInBits() > 64)
715       OpRegBankIdx[Idx] = PMI_FirstFPR;
716     else
717       OpRegBankIdx[Idx] = PMI_FirstGPR;
718   }
719 
720   unsigned Cost = 1;
721   // Some of the floating-point instructions have mixed GPR and FPR operands:
722   // fine-tune the computed mapping.
723   switch (Opc) {
724   case AArch64::G_DUP: {
725     Register ScalarReg = MI.getOperand(1).getReg();
726     LLT ScalarTy = MRI.getType(ScalarReg);
727     auto ScalarDef = MRI.getVRegDef(ScalarReg);
728     // s8 is an exception for G_DUP, which we always want on gpr.
729     if (ScalarTy.getSizeInBits() != 8 &&
730         (getRegBank(ScalarReg, MRI, TRI) == &AArch64::FPRRegBank ||
731          onlyDefinesFP(*ScalarDef, MRI, TRI)))
732       OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
733     else
734       OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
735     break;
736   }
737   case TargetOpcode::G_TRUNC: {
738     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
739     if (!SrcTy.isVector() && SrcTy.getSizeInBits() == 128)
740       OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
741     break;
742   }
743   case TargetOpcode::G_SITOFP:
744   case TargetOpcode::G_UITOFP: {
745     if (MRI.getType(MI.getOperand(0).getReg()).isVector())
746       break;
747     // Integer to FP conversions don't necessarily happen between GPR -> FPR
748     // regbanks. They can also be done within an FPR register.
749     Register SrcReg = MI.getOperand(1).getReg();
750     if (getRegBank(SrcReg, MRI, TRI) == &AArch64::FPRRegBank)
751       OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
752     else
753       OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
754     break;
755   }
756   case TargetOpcode::G_FPTOSI:
757   case TargetOpcode::G_FPTOUI:
758     if (MRI.getType(MI.getOperand(0).getReg()).isVector())
759       break;
760     OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};
761     break;
762   case TargetOpcode::G_FCMP: {
763     // If the result is a vector, it must use a FPR.
764     AArch64GenRegisterBankInfo::PartialMappingIdx Idx0 =
765         MRI.getType(MI.getOperand(0).getReg()).isVector() ? PMI_FirstFPR
766                                                           : PMI_FirstGPR;
767     OpRegBankIdx = {Idx0,
768                     /* Predicate */ PMI_None, PMI_FirstFPR, PMI_FirstFPR};
769     break;
770   }
771   case TargetOpcode::G_BITCAST:
772     // This is going to be a cross register bank copy and this is expensive.
773     if (OpRegBankIdx[0] != OpRegBankIdx[1])
774       Cost = copyCost(
775           *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[0]].RegBank,
776           *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[1]].RegBank,
777           OpSize[0]);
778     break;
779   case TargetOpcode::G_LOAD: {
780     // Loading in vector unit is slightly more expensive.
781     // This is actually only true for the LD1R and co instructions,
782     // but anyway for the fast mode this number does not matter and
783     // for the greedy mode the cost of the cross bank copy will
784     // offset this number.
785     // FIXME: Should be derived from the scheduling model.
786     if (OpRegBankIdx[0] != PMI_FirstGPR) {
787       Cost = 2;
788       break;
789     }
790 
791     if (cast<GLoad>(MI).isAtomic()) {
792       // Atomics always use GPR destinations. Don't refine any further.
793       OpRegBankIdx[0] = PMI_FirstGPR;
794       break;
795     }
796 
797     // Try to guess the type of the load from the MMO.
798     const auto &MMO = **MI.memoperands_begin();
799     const Value *LdVal = MMO.getValue();
800     if (LdVal) {
801       Type *EltTy = nullptr;
802       if (const GlobalValue *GV = dyn_cast<GlobalValue>(LdVal)) {
803         EltTy = GV->getValueType();
804       } else {
805         // FIXME: grubbing around uses is pretty ugly, but with no more
806         // `getPointerElementType` there's not much else we can do.
807         for (const auto *LdUser : LdVal->users()) {
808           if (isa<LoadInst>(LdUser)) {
809             EltTy = LdUser->getType();
810             break;
811           }
812           if (isa<StoreInst>(LdUser) && LdUser->getOperand(1) == LdVal) {
813             EltTy = LdUser->getOperand(0)->getType();
814             break;
815           }
816         }
817       }
818       if (EltTy && EltTy->isFPOrFPVectorTy()) {
819         OpRegBankIdx[0] = PMI_FirstFPR;
820         break;
821       }
822     }
823 
824     // Check if that load feeds fp instructions.
825     // In that case, we want the default mapping to be on FPR
826     // instead of blind map every scalar to GPR.
827     if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
828                [&](const MachineInstr &UseMI) {
829                  // If we have at least one direct use in a FP instruction,
830                  // assume this was a floating point load in the IR. If it was
831                  // not, we would have had a bitcast before reaching that
832                  // instruction.
833                  //
834                  // Int->FP conversion operations are also captured in
835                  // onlyDefinesFP().
836                  return onlyUsesFP(UseMI, MRI, TRI) ||
837                         onlyDefinesFP(UseMI, MRI, TRI);
838                }))
839       OpRegBankIdx[0] = PMI_FirstFPR;
840     break;
841   }
842   case TargetOpcode::G_STORE:
843     // Check if that store is fed by fp instructions.
844     if (OpRegBankIdx[0] == PMI_FirstGPR) {
845       Register VReg = MI.getOperand(0).getReg();
846       if (!VReg)
847         break;
848       MachineInstr *DefMI = MRI.getVRegDef(VReg);
849       if (onlyDefinesFP(*DefMI, MRI, TRI))
850         OpRegBankIdx[0] = PMI_FirstFPR;
851       break;
852     }
853     break;
854   case TargetOpcode::G_SELECT: {
855     // If the destination is FPR, preserve that.
856     if (OpRegBankIdx[0] != PMI_FirstGPR)
857       break;
858 
859     // If we're taking in vectors, we have no choice but to put everything on
860     // FPRs, except for the condition. The condition must always be on a GPR.
861     LLT SrcTy = MRI.getType(MI.getOperand(2).getReg());
862     if (SrcTy.isVector()) {
863       OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR, PMI_FirstFPR, PMI_FirstFPR};
864       break;
865     }
866 
867     // Try to minimize the number of copies. If we have more floating point
868     // constrained values than not, then we'll put everything on FPR. Otherwise,
869     // everything has to be on GPR.
870     unsigned NumFP = 0;
871 
872     // Check if the uses of the result always produce floating point values.
873     //
874     // For example:
875     //
876     // %z = G_SELECT %cond %x %y
877     // fpr = G_FOO %z ...
878     if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
879                [&](MachineInstr &MI) { return onlyUsesFP(MI, MRI, TRI); }))
880       ++NumFP;
881 
882     // Check if the defs of the source values always produce floating point
883     // values.
884     //
885     // For example:
886     //
887     // %x = G_SOMETHING_ALWAYS_FLOAT %a ...
888     // %z = G_SELECT %cond %x %y
889     //
890     // Also check whether or not the sources have already been decided to be
891     // FPR. Keep track of this.
892     //
893     // This doesn't check the condition, since it's just whatever is in NZCV.
894     // This isn't passed explicitly in a register to fcsel/csel.
895     for (unsigned Idx = 2; Idx < 4; ++Idx) {
896       Register VReg = MI.getOperand(Idx).getReg();
897       MachineInstr *DefMI = MRI.getVRegDef(VReg);
898       if (getRegBank(VReg, MRI, TRI) == &AArch64::FPRRegBank ||
899           onlyDefinesFP(*DefMI, MRI, TRI))
900         ++NumFP;
901     }
902 
903     // If we have more FP constraints than not, then move everything over to
904     // FPR.
905     if (NumFP >= 2)
906       OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR, PMI_FirstFPR, PMI_FirstFPR};
907 
908     break;
909   }
910   case TargetOpcode::G_UNMERGE_VALUES: {
911     // If the first operand belongs to a FPR register bank, then make sure that
912     // we preserve that.
913     if (OpRegBankIdx[0] != PMI_FirstGPR)
914       break;
915 
916     LLT SrcTy = MRI.getType(MI.getOperand(MI.getNumOperands()-1).getReg());
917     // UNMERGE into scalars from a vector should always use FPR.
918     // Likewise if any of the uses are FP instructions.
919     if (SrcTy.isVector() || SrcTy == LLT::scalar(128) ||
920         any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
921                [&](MachineInstr &MI) { return onlyUsesFP(MI, MRI, TRI); })) {
922       // Set the register bank of every operand to FPR.
923       for (unsigned Idx = 0, NumOperands = MI.getNumOperands();
924            Idx < NumOperands; ++Idx)
925         OpRegBankIdx[Idx] = PMI_FirstFPR;
926     }
927     break;
928   }
929   case TargetOpcode::G_EXTRACT_VECTOR_ELT:
930     // Destination and source need to be FPRs.
931     OpRegBankIdx[0] = PMI_FirstFPR;
932     OpRegBankIdx[1] = PMI_FirstFPR;
933 
934     // Index needs to be a GPR.
935     OpRegBankIdx[2] = PMI_FirstGPR;
936     break;
937   case TargetOpcode::G_INSERT_VECTOR_ELT:
938     OpRegBankIdx[0] = PMI_FirstFPR;
939     OpRegBankIdx[1] = PMI_FirstFPR;
940 
941     // The element may be either a GPR or FPR. Preserve that behaviour.
942     if (getRegBank(MI.getOperand(2).getReg(), MRI, TRI) == &AArch64::FPRRegBank)
943       OpRegBankIdx[2] = PMI_FirstFPR;
944     else
945       OpRegBankIdx[2] = PMI_FirstGPR;
946 
947     // Index needs to be a GPR.
948     OpRegBankIdx[3] = PMI_FirstGPR;
949     break;
950   case TargetOpcode::G_EXTRACT: {
951     // For s128 sources we have to use fpr unless we know otherwise.
952     auto Src = MI.getOperand(1).getReg();
953     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
954     if (SrcTy.getSizeInBits() != 128)
955       break;
956     auto Idx = MRI.getRegClassOrNull(Src) == &AArch64::XSeqPairsClassRegClass
957                    ? PMI_FirstGPR
958                    : PMI_FirstFPR;
959     OpRegBankIdx[0] = Idx;
960     OpRegBankIdx[1] = Idx;
961     break;
962   }
963   case TargetOpcode::G_BUILD_VECTOR: {
964     // If the first source operand belongs to a FPR register bank, then make
965     // sure that we preserve that.
966     if (OpRegBankIdx[1] != PMI_FirstGPR)
967       break;
968     Register VReg = MI.getOperand(1).getReg();
969     if (!VReg)
970       break;
971 
972     // Get the instruction that defined the source operand reg, and check if
973     // it's a floating point operation. Or, if it's a type like s16 which
974     // doesn't have a exact size gpr register class. The exception is if the
975     // build_vector has all constant operands, which may be better to leave as
976     // gpr without copies, so it can be matched in imported patterns.
977     MachineInstr *DefMI = MRI.getVRegDef(VReg);
978     unsigned DefOpc = DefMI->getOpcode();
979     const LLT SrcTy = MRI.getType(VReg);
980     if (all_of(MI.operands(), [&](const MachineOperand &Op) {
981           return Op.isDef() || MRI.getVRegDef(Op.getReg())->getOpcode() ==
982                                    TargetOpcode::G_CONSTANT;
983         }))
984       break;
985     if (isPreISelGenericFloatingPointOpcode(DefOpc) ||
986         SrcTy.getSizeInBits() < 32 ||
987         getRegBank(VReg, MRI, TRI) == &AArch64::FPRRegBank) {
988       // Have a floating point op.
989       // Make sure every operand gets mapped to a FPR register class.
990       unsigned NumOperands = MI.getNumOperands();
991       for (unsigned Idx = 0; Idx < NumOperands; ++Idx)
992         OpRegBankIdx[Idx] = PMI_FirstFPR;
993     }
994     break;
995   }
996   case TargetOpcode::G_VECREDUCE_FADD:
997   case TargetOpcode::G_VECREDUCE_FMUL:
998   case TargetOpcode::G_VECREDUCE_FMAX:
999   case TargetOpcode::G_VECREDUCE_FMIN:
1000   case TargetOpcode::G_VECREDUCE_ADD:
1001   case TargetOpcode::G_VECREDUCE_MUL:
1002   case TargetOpcode::G_VECREDUCE_AND:
1003   case TargetOpcode::G_VECREDUCE_OR:
1004   case TargetOpcode::G_VECREDUCE_XOR:
1005   case TargetOpcode::G_VECREDUCE_SMAX:
1006   case TargetOpcode::G_VECREDUCE_SMIN:
1007   case TargetOpcode::G_VECREDUCE_UMAX:
1008   case TargetOpcode::G_VECREDUCE_UMIN:
1009     // Reductions produce a scalar value from a vector, the scalar should be on
1010     // FPR bank.
1011     OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
1012     break;
1013   case TargetOpcode::G_VECREDUCE_SEQ_FADD:
1014   case TargetOpcode::G_VECREDUCE_SEQ_FMUL:
1015     // These reductions also take a scalar accumulator input.
1016     // Assign them FPR for now.
1017     OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR, PMI_FirstFPR};
1018     break;
1019   case TargetOpcode::G_INTRINSIC: {
1020     // Check if we know that the intrinsic has any constraints on its register
1021     // banks. If it does, then update the mapping accordingly.
1022     unsigned Idx = 0;
1023     if (!isFPIntrinsic(MRI, MI))
1024       break;
1025     for (const auto &Op : MI.explicit_operands()) {
1026       if (Op.isReg())
1027         OpRegBankIdx[Idx] = PMI_FirstFPR;
1028       ++Idx;
1029     }
1030     break;
1031   }
1032   case TargetOpcode::G_LROUND:
1033   case TargetOpcode::G_LLROUND: {
1034     // Source is always floating point and destination is always integer.
1035     OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};
1036     break;
1037   }
1038   }
1039 
1040   // Finally construct the computed mapping.
1041   SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
1042   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
1043     if (MI.getOperand(Idx).isReg() && MI.getOperand(Idx).getReg()) {
1044       LLT Ty = MRI.getType(MI.getOperand(Idx).getReg());
1045       if (!Ty.isValid())
1046         continue;
1047       auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
1048       if (!Mapping->isValid())
1049         return getInvalidInstructionMapping();
1050 
1051       OpdsMapping[Idx] = Mapping;
1052     }
1053   }
1054 
1055   return getInstructionMapping(DefaultMappingID, Cost,
1056                                getOperandsMapping(OpdsMapping), NumOperands);
1057 }
1058