AArch64RegisterBankInfo.cpp 39 KB

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