xref: /llvm-project/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp (revision e9cb44090ff7b3feda386ca1ee1252ab47c0617e)
11c3f7f17SFangrui Song //===- X86RegisterBankInfo.cpp -----------------------------------*- C++ -*-==//
21c3f7f17SFangrui Song //
31c3f7f17SFangrui Song // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41c3f7f17SFangrui Song // See https://llvm.org/LICENSE.txt for license information.
51c3f7f17SFangrui Song // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61c3f7f17SFangrui Song //
71c3f7f17SFangrui Song //===----------------------------------------------------------------------===//
81c3f7f17SFangrui Song /// \file
91c3f7f17SFangrui Song /// This file implements the targeting of the RegisterBankInfo class for X86.
101c3f7f17SFangrui Song /// \todo This should be generated by TableGen.
111c3f7f17SFangrui Song //===----------------------------------------------------------------------===//
121c3f7f17SFangrui Song 
131c3f7f17SFangrui Song #include "X86RegisterBankInfo.h"
141c3f7f17SFangrui Song #include "X86InstrInfo.h"
15564b81dbSMalaySanghiIntel #include "X86Subtarget.h"
1692e96c7bSMalay Sanghi #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
1792e96c7bSMalay Sanghi #include "llvm/CodeGen/GlobalISel/Utils.h"
181c3f7f17SFangrui Song #include "llvm/CodeGen/MachineRegisterInfo.h"
191c3f7f17SFangrui Song #include "llvm/CodeGen/RegisterBank.h"
201c3f7f17SFangrui Song #include "llvm/CodeGen/RegisterBankInfo.h"
211c3f7f17SFangrui Song #include "llvm/CodeGen/TargetRegisterInfo.h"
2292e96c7bSMalay Sanghi #include "llvm/IR/IntrinsicsX86.h"
231c3f7f17SFangrui Song 
241c3f7f17SFangrui Song #define GET_TARGET_REGBANK_IMPL
251c3f7f17SFangrui Song #include "X86GenRegisterBank.inc"
261c3f7f17SFangrui Song 
271c3f7f17SFangrui Song using namespace llvm;
281c3f7f17SFangrui Song // This file will be TableGen'ed at some point.
291c3f7f17SFangrui Song #define GET_TARGET_REGBANK_INFO_IMPL
301c3f7f17SFangrui Song #include "X86GenRegisterBankInfo.def"
311c3f7f17SFangrui Song 
321c3f7f17SFangrui Song X86RegisterBankInfo::X86RegisterBankInfo(const TargetRegisterInfo &TRI) {
331c3f7f17SFangrui Song 
341c3f7f17SFangrui Song   // validate RegBank initialization.
351c3f7f17SFangrui Song   const RegisterBank &RBGPR = getRegBank(X86::GPRRegBankID);
361c3f7f17SFangrui Song   (void)RBGPR;
371c3f7f17SFangrui Song   assert(&X86::GPRRegBank == &RBGPR && "Incorrect RegBanks inizalization.");
381c3f7f17SFangrui Song 
391c3f7f17SFangrui Song   // The GPR register bank is fully defined by all the registers in
401c3f7f17SFangrui Song   // GR64 + its subclasses.
411c3f7f17SFangrui Song   assert(RBGPR.covers(*TRI.getRegClass(X86::GR64RegClassID)) &&
421c3f7f17SFangrui Song          "Subclass not added?");
431c3f7f17SFangrui Song   assert(getMaximumSize(RBGPR.getID()) == 64 &&
441c3f7f17SFangrui Song          "GPRs should hold up to 64-bit");
451c3f7f17SFangrui Song }
461c3f7f17SFangrui Song 
4792e96c7bSMalay Sanghi // \returns true if a given intrinsic only uses and defines FPRs.
4892e96c7bSMalay Sanghi static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
4992e96c7bSMalay Sanghi                           const MachineInstr &MI) {
5092e96c7bSMalay Sanghi   // TODO: Add more intrinsics.
5192e96c7bSMalay Sanghi   switch (cast<GIntrinsic>(MI).getIntrinsicID()) {
5292e96c7bSMalay Sanghi   default:
5392e96c7bSMalay Sanghi     return false;
5492e96c7bSMalay Sanghi   // SSE1
5592e96c7bSMalay Sanghi   case Intrinsic::x86_sse_rcp_ss:
5692e96c7bSMalay Sanghi   case Intrinsic::x86_sse_rcp_ps:
5792e96c7bSMalay Sanghi   case Intrinsic::x86_sse_rsqrt_ss:
5892e96c7bSMalay Sanghi   case Intrinsic::x86_sse_rsqrt_ps:
5992e96c7bSMalay Sanghi   case Intrinsic::x86_sse_min_ss:
6092e96c7bSMalay Sanghi   case Intrinsic::x86_sse_min_ps:
6192e96c7bSMalay Sanghi   case Intrinsic::x86_sse_max_ss:
6292e96c7bSMalay Sanghi   case Intrinsic::x86_sse_max_ps:
6392e96c7bSMalay Sanghi     return true;
6492e96c7bSMalay Sanghi   }
6592e96c7bSMalay Sanghi   return false;
6692e96c7bSMalay Sanghi }
6792e96c7bSMalay Sanghi 
6892e96c7bSMalay Sanghi bool X86RegisterBankInfo::hasFPConstraints(const MachineInstr &MI,
6992e96c7bSMalay Sanghi                                            const MachineRegisterInfo &MRI,
7092e96c7bSMalay Sanghi                                            const TargetRegisterInfo &TRI,
7192e96c7bSMalay Sanghi                                            unsigned Depth) const {
7292e96c7bSMalay Sanghi   unsigned Op = MI.getOpcode();
7392e96c7bSMalay Sanghi   if (Op == TargetOpcode::G_INTRINSIC && isFPIntrinsic(MRI, MI))
7492e96c7bSMalay Sanghi     return true;
7592e96c7bSMalay Sanghi 
7692e96c7bSMalay Sanghi   // Do we have an explicit floating point instruction?
7792e96c7bSMalay Sanghi   if (isPreISelGenericFloatingPointOpcode(Op))
7892e96c7bSMalay Sanghi     return true;
7992e96c7bSMalay Sanghi 
8092e96c7bSMalay Sanghi   // No. Check if we have a copy-like instruction. If we do, then we could
8192e96c7bSMalay Sanghi   // still be fed by floating point instructions.
8292e96c7bSMalay Sanghi   if (Op != TargetOpcode::COPY && !MI.isPHI() &&
8392e96c7bSMalay Sanghi       !isPreISelGenericOptimizationHint(Op))
8492e96c7bSMalay Sanghi     return false;
8592e96c7bSMalay Sanghi 
8692e96c7bSMalay Sanghi   // Check if we already know the register bank.
8792e96c7bSMalay Sanghi   auto *RB = getRegBank(MI.getOperand(0).getReg(), MRI, TRI);
8892e96c7bSMalay Sanghi   if (RB == &getRegBank(X86::PSRRegBankID))
8992e96c7bSMalay Sanghi     return true;
9092e96c7bSMalay Sanghi   if (RB == &getRegBank(X86::GPRRegBankID))
9192e96c7bSMalay Sanghi     return false;
9292e96c7bSMalay Sanghi 
9392e96c7bSMalay Sanghi   // We don't know anything.
9492e96c7bSMalay Sanghi   //
9592e96c7bSMalay Sanghi   // If we have a phi, we may be able to infer that it will be assigned a fp
9692e96c7bSMalay Sanghi   // type based off of its inputs.
9792e96c7bSMalay Sanghi   if (!MI.isPHI() || Depth > MaxFPRSearchDepth)
9892e96c7bSMalay Sanghi     return false;
9992e96c7bSMalay Sanghi 
10092e96c7bSMalay Sanghi   return any_of(MI.explicit_uses(), [&](const MachineOperand &Op) {
10192e96c7bSMalay Sanghi     return Op.isReg() &&
10292e96c7bSMalay Sanghi            onlyDefinesFP(*MRI.getVRegDef(Op.getReg()), MRI, TRI, Depth + 1);
10392e96c7bSMalay Sanghi   });
10492e96c7bSMalay Sanghi }
10592e96c7bSMalay Sanghi 
10692e96c7bSMalay Sanghi bool X86RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
10792e96c7bSMalay Sanghi                                      const MachineRegisterInfo &MRI,
10892e96c7bSMalay Sanghi                                      const TargetRegisterInfo &TRI,
10992e96c7bSMalay Sanghi                                      unsigned Depth) const {
11092e96c7bSMalay Sanghi   switch (MI.getOpcode()) {
11192e96c7bSMalay Sanghi   case TargetOpcode::G_FPTOSI:
11292e96c7bSMalay Sanghi   case TargetOpcode::G_FPTOUI:
11392e96c7bSMalay Sanghi   case TargetOpcode::G_FCMP:
11492e96c7bSMalay Sanghi   case TargetOpcode::G_LROUND:
11592e96c7bSMalay Sanghi   case TargetOpcode::G_LLROUND:
11692e96c7bSMalay Sanghi   case TargetOpcode::G_INTRINSIC_TRUNC:
11792e96c7bSMalay Sanghi   case TargetOpcode::G_INTRINSIC_ROUND:
11892e96c7bSMalay Sanghi     return true;
11992e96c7bSMalay Sanghi   default:
12092e96c7bSMalay Sanghi     break;
12192e96c7bSMalay Sanghi   }
12292e96c7bSMalay Sanghi   return hasFPConstraints(MI, MRI, TRI, Depth);
12392e96c7bSMalay Sanghi }
12492e96c7bSMalay Sanghi 
12592e96c7bSMalay Sanghi bool X86RegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
12692e96c7bSMalay Sanghi                                         const MachineRegisterInfo &MRI,
12792e96c7bSMalay Sanghi                                         const TargetRegisterInfo &TRI,
12892e96c7bSMalay Sanghi                                         unsigned Depth) const {
12992e96c7bSMalay Sanghi   switch (MI.getOpcode()) {
13092e96c7bSMalay Sanghi   case TargetOpcode::G_SITOFP:
13192e96c7bSMalay Sanghi   case TargetOpcode::G_UITOFP:
13292e96c7bSMalay Sanghi     return true;
13392e96c7bSMalay Sanghi   default:
13492e96c7bSMalay Sanghi     break;
13592e96c7bSMalay Sanghi   }
13692e96c7bSMalay Sanghi   return hasFPConstraints(MI, MRI, TRI, Depth);
13792e96c7bSMalay Sanghi }
13892e96c7bSMalay Sanghi 
1391c3f7f17SFangrui Song X86GenRegisterBankInfo::PartialMappingIdx
140564b81dbSMalaySanghiIntel X86GenRegisterBankInfo::getPartialMappingIdx(const MachineInstr &MI,
141564b81dbSMalaySanghiIntel                                              const LLT &Ty, bool isFP) {
142564b81dbSMalaySanghiIntel   const MachineFunction *MF = MI.getMF();
143564b81dbSMalaySanghiIntel   const X86Subtarget *ST = &MF->getSubtarget<X86Subtarget>();
144564b81dbSMalaySanghiIntel   bool HasSSE1 = ST->hasSSE1();
145564b81dbSMalaySanghiIntel   bool HasSSE2 = ST->hasSSE2();
146564b81dbSMalaySanghiIntel   // 80 bits is only generated for X87 floating points.
147564b81dbSMalaySanghiIntel   if (Ty.getSizeInBits() == 80)
148564b81dbSMalaySanghiIntel     isFP = true;
1491c3f7f17SFangrui Song   if ((Ty.isScalar() && !isFP) || Ty.isPointer()) {
1501c3f7f17SFangrui Song     switch (Ty.getSizeInBits()) {
1511c3f7f17SFangrui Song     case 1:
1521c3f7f17SFangrui Song     case 8:
1531c3f7f17SFangrui Song       return PMI_GPR8;
1541c3f7f17SFangrui Song     case 16:
1551c3f7f17SFangrui Song       return PMI_GPR16;
1561c3f7f17SFangrui Song     case 32:
1571c3f7f17SFangrui Song       return PMI_GPR32;
1581c3f7f17SFangrui Song     case 64:
1591c3f7f17SFangrui Song       return PMI_GPR64;
1601c3f7f17SFangrui Song     case 128:
1611c3f7f17SFangrui Song       return PMI_VEC128;
1621c3f7f17SFangrui Song       break;
1631c3f7f17SFangrui Song     default:
1641c3f7f17SFangrui Song       llvm_unreachable("Unsupported register size.");
1651c3f7f17SFangrui Song     }
1661c3f7f17SFangrui Song   } else if (Ty.isScalar()) {
1671c3f7f17SFangrui Song     switch (Ty.getSizeInBits()) {
1681c3f7f17SFangrui Song     case 32:
169564b81dbSMalaySanghiIntel       return HasSSE1 ? PMI_FP32 : PMI_PSR32;
1701c3f7f17SFangrui Song     case 64:
171564b81dbSMalaySanghiIntel       return HasSSE2 ? PMI_FP64 : PMI_PSR64;
1721c3f7f17SFangrui Song     case 128:
1731c3f7f17SFangrui Song       return PMI_VEC128;
174564b81dbSMalaySanghiIntel     case 80:
175564b81dbSMalaySanghiIntel       return PMI_PSR80;
1761c3f7f17SFangrui Song     default:
1771c3f7f17SFangrui Song       llvm_unreachable("Unsupported register size.");
1781c3f7f17SFangrui Song     }
1791c3f7f17SFangrui Song   } else {
1801c3f7f17SFangrui Song     switch (Ty.getSizeInBits()) {
1811c3f7f17SFangrui Song     case 128:
1821c3f7f17SFangrui Song       return PMI_VEC128;
1831c3f7f17SFangrui Song     case 256:
1841c3f7f17SFangrui Song       return PMI_VEC256;
1851c3f7f17SFangrui Song     case 512:
1861c3f7f17SFangrui Song       return PMI_VEC512;
1871c3f7f17SFangrui Song     default:
1881c3f7f17SFangrui Song       llvm_unreachable("Unsupported register size.");
1891c3f7f17SFangrui Song     }
1901c3f7f17SFangrui Song   }
1911c3f7f17SFangrui Song 
1921c3f7f17SFangrui Song   return PMI_None;
1931c3f7f17SFangrui Song }
1941c3f7f17SFangrui Song 
1951c3f7f17SFangrui Song void X86RegisterBankInfo::getInstrPartialMappingIdxs(
1961c3f7f17SFangrui Song     const MachineInstr &MI, const MachineRegisterInfo &MRI, const bool isFP,
1971c3f7f17SFangrui Song     SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx) {
1981c3f7f17SFangrui Song 
1991c3f7f17SFangrui Song   unsigned NumOperands = MI.getNumOperands();
2001c3f7f17SFangrui Song   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
2011c3f7f17SFangrui Song     auto &MO = MI.getOperand(Idx);
2021c3f7f17SFangrui Song     if (!MO.isReg() || !MO.getReg())
2031c3f7f17SFangrui Song       OpRegBankIdx[Idx] = PMI_None;
2041c3f7f17SFangrui Song     else
205564b81dbSMalaySanghiIntel       OpRegBankIdx[Idx] =
206564b81dbSMalaySanghiIntel           getPartialMappingIdx(MI, MRI.getType(MO.getReg()), isFP);
2071c3f7f17SFangrui Song   }
2081c3f7f17SFangrui Song }
2091c3f7f17SFangrui Song 
2101c3f7f17SFangrui Song bool X86RegisterBankInfo::getInstrValueMapping(
2111c3f7f17SFangrui Song     const MachineInstr &MI,
2121c3f7f17SFangrui Song     const SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx,
2131c3f7f17SFangrui Song     SmallVectorImpl<const ValueMapping *> &OpdsMapping) {
2141c3f7f17SFangrui Song 
2151c3f7f17SFangrui Song   unsigned NumOperands = MI.getNumOperands();
2161c3f7f17SFangrui Song   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
2171c3f7f17SFangrui Song     if (!MI.getOperand(Idx).isReg())
2181c3f7f17SFangrui Song       continue;
2191c3f7f17SFangrui Song     if (!MI.getOperand(Idx).getReg())
2201c3f7f17SFangrui Song       continue;
2211c3f7f17SFangrui Song 
2221c3f7f17SFangrui Song     auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1);
2231c3f7f17SFangrui Song     if (!Mapping->isValid())
2241c3f7f17SFangrui Song       return false;
2251c3f7f17SFangrui Song 
2261c3f7f17SFangrui Song     OpdsMapping[Idx] = Mapping;
2271c3f7f17SFangrui Song   }
2281c3f7f17SFangrui Song   return true;
2291c3f7f17SFangrui Song }
2301c3f7f17SFangrui Song 
2311c3f7f17SFangrui Song const RegisterBankInfo::InstructionMapping &
2321c3f7f17SFangrui Song X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI,
2331c3f7f17SFangrui Song                                             bool isFP) const {
2341c3f7f17SFangrui Song   const MachineFunction &MF = *MI.getParent()->getParent();
2351c3f7f17SFangrui Song   const MachineRegisterInfo &MRI = MF.getRegInfo();
2361c3f7f17SFangrui Song 
2371c3f7f17SFangrui Song   unsigned NumOperands = MI.getNumOperands();
2381c3f7f17SFangrui Song   LLT Ty = MRI.getType(MI.getOperand(0).getReg());
2391c3f7f17SFangrui Song 
2401c3f7f17SFangrui Song   if (NumOperands != 3 || (Ty != MRI.getType(MI.getOperand(1).getReg())) ||
2411c3f7f17SFangrui Song       (Ty != MRI.getType(MI.getOperand(2).getReg())))
2421c3f7f17SFangrui Song     llvm_unreachable("Unsupported operand mapping yet.");
2431c3f7f17SFangrui Song 
244564b81dbSMalaySanghiIntel   auto Mapping = getValueMapping(getPartialMappingIdx(MI, Ty, isFP), 3);
2451c3f7f17SFangrui Song   return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
2461c3f7f17SFangrui Song }
2471c3f7f17SFangrui Song 
2481c3f7f17SFangrui Song const RegisterBankInfo::InstructionMapping &
2491c3f7f17SFangrui Song X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
2501c3f7f17SFangrui Song   const MachineFunction &MF = *MI.getParent()->getParent();
25192e96c7bSMalay Sanghi   const TargetSubtargetInfo &STI = MF.getSubtarget();
25292e96c7bSMalay Sanghi   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
2531c3f7f17SFangrui Song   const MachineRegisterInfo &MRI = MF.getRegInfo();
2541c3f7f17SFangrui Song   unsigned Opc = MI.getOpcode();
2551c3f7f17SFangrui Song 
25692e96c7bSMalay Sanghi   // Try the default logic for non-generic instructions that are either
25792e96c7bSMalay Sanghi   // copies or already have some operands assigned to banks.
2581c3f7f17SFangrui Song   if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
2591c3f7f17SFangrui Song     const InstructionMapping &Mapping = getInstrMappingImpl(MI);
2601c3f7f17SFangrui Song     if (Mapping.isValid())
2611c3f7f17SFangrui Song       return Mapping;
2621c3f7f17SFangrui Song   }
2631c3f7f17SFangrui Song 
2641c3f7f17SFangrui Song   switch (Opc) {
2651c3f7f17SFangrui Song   case TargetOpcode::G_ADD:
2661c3f7f17SFangrui Song   case TargetOpcode::G_SUB:
2671c3f7f17SFangrui Song   case TargetOpcode::G_MUL:
2681c3f7f17SFangrui Song     return getSameOperandsMapping(MI, false);
2691c3f7f17SFangrui Song   case TargetOpcode::G_FADD:
2701c3f7f17SFangrui Song   case TargetOpcode::G_FSUB:
2711c3f7f17SFangrui Song   case TargetOpcode::G_FMUL:
2721c3f7f17SFangrui Song   case TargetOpcode::G_FDIV:
2731c3f7f17SFangrui Song     return getSameOperandsMapping(MI, true);
2741c3f7f17SFangrui Song   case TargetOpcode::G_SHL:
2751c3f7f17SFangrui Song   case TargetOpcode::G_LSHR:
2761c3f7f17SFangrui Song   case TargetOpcode::G_ASHR: {
2771c3f7f17SFangrui Song     unsigned NumOperands = MI.getNumOperands();
2781c3f7f17SFangrui Song     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
2791c3f7f17SFangrui Song 
280564b81dbSMalaySanghiIntel     auto Mapping = getValueMapping(getPartialMappingIdx(MI, Ty, false), 3);
2811c3f7f17SFangrui Song     return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
2821c3f7f17SFangrui Song   }
2831c3f7f17SFangrui Song   default:
2841c3f7f17SFangrui Song     break;
2851c3f7f17SFangrui Song   }
2861c3f7f17SFangrui Song 
2871c3f7f17SFangrui Song   unsigned NumOperands = MI.getNumOperands();
2881c3f7f17SFangrui Song   SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
2891c3f7f17SFangrui Song 
2901c3f7f17SFangrui Song   switch (Opc) {
2911c3f7f17SFangrui Song   case TargetOpcode::G_FPEXT:
2921c3f7f17SFangrui Song   case TargetOpcode::G_FPTRUNC:
2931c3f7f17SFangrui Song   case TargetOpcode::G_FCONSTANT:
29492e96c7bSMalay Sanghi     // Instruction having only floating-point operands (all scalars in
29592e96c7bSMalay Sanghi     // VECRReg)
296564b81dbSMalaySanghiIntel     getInstrPartialMappingIdxs(MI, MRI, /* isFP= */ true, OpRegBankIdx);
2971c3f7f17SFangrui Song     break;
2981c3f7f17SFangrui Song   case TargetOpcode::G_SITOFP:
299*e9cb4409SEvgenii Kudriashov   case TargetOpcode::G_FPTOSI:
300*e9cb4409SEvgenii Kudriashov   case TargetOpcode::G_UITOFP:
301*e9cb4409SEvgenii Kudriashov   case TargetOpcode::G_FPTOUI: {
30292e96c7bSMalay Sanghi     // Some of the floating-point instructions have mixed GPR and FP
30392e96c7bSMalay Sanghi     // operands: fine-tune the computed mapping.
3041c3f7f17SFangrui Song     auto &Op0 = MI.getOperand(0);
3051c3f7f17SFangrui Song     auto &Op1 = MI.getOperand(1);
3061c3f7f17SFangrui Song     const LLT Ty0 = MRI.getType(Op0.getReg());
3071c3f7f17SFangrui Song     const LLT Ty1 = MRI.getType(Op1.getReg());
3081c3f7f17SFangrui Song 
309*e9cb4409SEvgenii Kudriashov     bool FirstArgIsFP =
310*e9cb4409SEvgenii Kudriashov         Opc == TargetOpcode::G_SITOFP || Opc == TargetOpcode::G_UITOFP;
311564b81dbSMalaySanghiIntel     OpRegBankIdx[0] = getPartialMappingIdx(MI, Ty0, /* isFP= */ FirstArgIsFP);
312*e9cb4409SEvgenii Kudriashov     OpRegBankIdx[1] = getPartialMappingIdx(MI, Ty1, /* isFP= */ !FirstArgIsFP);
3131c3f7f17SFangrui Song     break;
3141c3f7f17SFangrui Song   }
3151c3f7f17SFangrui Song   case TargetOpcode::G_FCMP: {
3161c3f7f17SFangrui Song     LLT Ty1 = MRI.getType(MI.getOperand(2).getReg());
3171c3f7f17SFangrui Song     LLT Ty2 = MRI.getType(MI.getOperand(3).getReg());
3181c3f7f17SFangrui Song     (void)Ty2;
3191c3f7f17SFangrui Song     assert(Ty1.getSizeInBits() == Ty2.getSizeInBits() &&
3201c3f7f17SFangrui Song            "Mismatched operand sizes for G_FCMP");
3211c3f7f17SFangrui Song 
3221c3f7f17SFangrui Song     unsigned Size = Ty1.getSizeInBits();
3231c3f7f17SFangrui Song     (void)Size;
3241c3f7f17SFangrui Song     assert((Size == 32 || Size == 64) && "Unsupported size for G_FCMP");
3251c3f7f17SFangrui Song 
326564b81dbSMalaySanghiIntel     auto FpRegBank = getPartialMappingIdx(MI, Ty1, /* isFP= */ true);
3271c3f7f17SFangrui Song     OpRegBankIdx = {PMI_GPR8,
3281c3f7f17SFangrui Song                     /* Predicate */ PMI_None, FpRegBank, FpRegBank};
3291c3f7f17SFangrui Song     break;
3301c3f7f17SFangrui Song   }
3311c3f7f17SFangrui Song   case TargetOpcode::G_TRUNC:
3321c3f7f17SFangrui Song   case TargetOpcode::G_ANYEXT: {
3331c3f7f17SFangrui Song     auto &Op0 = MI.getOperand(0);
3341c3f7f17SFangrui Song     auto &Op1 = MI.getOperand(1);
3351c3f7f17SFangrui Song     const LLT Ty0 = MRI.getType(Op0.getReg());
3361c3f7f17SFangrui Song     const LLT Ty1 = MRI.getType(Op1.getReg());
3371c3f7f17SFangrui Song 
3381c3f7f17SFangrui Song     bool isFPTrunc = (Ty0.getSizeInBits() == 32 || Ty0.getSizeInBits() == 64) &&
3391c3f7f17SFangrui Song                      Ty1.getSizeInBits() == 128 && Opc == TargetOpcode::G_TRUNC;
3401c3f7f17SFangrui Song     bool isFPAnyExt =
3411c3f7f17SFangrui Song         Ty0.getSizeInBits() == 128 &&
3421c3f7f17SFangrui Song         (Ty1.getSizeInBits() == 32 || Ty1.getSizeInBits() == 64) &&
3431c3f7f17SFangrui Song         Opc == TargetOpcode::G_ANYEXT;
3441c3f7f17SFangrui Song 
345564b81dbSMalaySanghiIntel     getInstrPartialMappingIdxs(MI, MRI, /* isFP= */ isFPTrunc || isFPAnyExt,
3461c3f7f17SFangrui Song                                OpRegBankIdx);
34792e96c7bSMalay Sanghi     break;
34892e96c7bSMalay Sanghi   }
34992e96c7bSMalay Sanghi   case TargetOpcode::G_LOAD: {
35092e96c7bSMalay Sanghi     // Check if that load feeds fp instructions.
35192e96c7bSMalay Sanghi     // In that case, we want the default mapping to be on FPR
35292e96c7bSMalay Sanghi     // instead of blind map every scalar to GPR.
35392e96c7bSMalay Sanghi     bool IsFP = any_of(MRI.use_nodbg_instructions(cast<GLoad>(MI).getDstReg()),
35492e96c7bSMalay Sanghi                        [&](const MachineInstr &UseMI) {
35592e96c7bSMalay Sanghi                          // If we have at least one direct use in a FP
35692e96c7bSMalay Sanghi                          // instruction, assume this was a floating point load
35792e96c7bSMalay Sanghi                          // in the IR. If it was not, we would have had a
35892e96c7bSMalay Sanghi                          // bitcast before reaching that instruction.
35992e96c7bSMalay Sanghi                          return onlyUsesFP(UseMI, MRI, TRI);
36092e96c7bSMalay Sanghi                        });
36192e96c7bSMalay Sanghi     getInstrPartialMappingIdxs(MI, MRI, IsFP, OpRegBankIdx);
36292e96c7bSMalay Sanghi     break;
36392e96c7bSMalay Sanghi   }
36492e96c7bSMalay Sanghi   case TargetOpcode::G_STORE: {
36592e96c7bSMalay Sanghi     // Check if that store is fed by fp instructions.
36692e96c7bSMalay Sanghi     Register VReg = cast<GStore>(MI).getValueReg();
36792e96c7bSMalay Sanghi     if (!VReg)
36892e96c7bSMalay Sanghi       break;
36992e96c7bSMalay Sanghi     MachineInstr *DefMI = MRI.getVRegDef(VReg);
37092e96c7bSMalay Sanghi     bool IsFP = onlyDefinesFP(*DefMI, MRI, TRI);
37192e96c7bSMalay Sanghi     getInstrPartialMappingIdxs(MI, MRI, IsFP, OpRegBankIdx);
37292e96c7bSMalay Sanghi     break;
37392e96c7bSMalay Sanghi   }
3741c3f7f17SFangrui Song   default:
37592e96c7bSMalay Sanghi     // Track the bank of each register, use NotFP mapping (all scalars in
37692e96c7bSMalay Sanghi     // GPRs)
377564b81dbSMalaySanghiIntel     getInstrPartialMappingIdxs(MI, MRI, /* isFP= */ false, OpRegBankIdx);
3781c3f7f17SFangrui Song     break;
3791c3f7f17SFangrui Song   }
3801c3f7f17SFangrui Song 
3811c3f7f17SFangrui Song   // Finally construct the computed mapping.
3821c3f7f17SFangrui Song   SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
3831c3f7f17SFangrui Song   if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
3841c3f7f17SFangrui Song     return getInvalidInstructionMapping();
3851c3f7f17SFangrui Song 
3861c3f7f17SFangrui Song   return getInstructionMapping(DefaultMappingID, /* Cost */ 1,
3871c3f7f17SFangrui Song                                getOperandsMapping(OpdsMapping), NumOperands);
3881c3f7f17SFangrui Song }
3891c3f7f17SFangrui Song 
3901c3f7f17SFangrui Song void X86RegisterBankInfo::applyMappingImpl(
3911c3f7f17SFangrui Song     MachineIRBuilder &Builder, const OperandsMapper &OpdMapper) const {
3921c3f7f17SFangrui Song   return applyDefaultMapping(OpdMapper);
3931c3f7f17SFangrui Song }
3941c3f7f17SFangrui Song 
3951c3f7f17SFangrui Song RegisterBankInfo::InstructionMappings
3961c3f7f17SFangrui Song X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
3971c3f7f17SFangrui Song 
3981c3f7f17SFangrui Song   const MachineFunction &MF = *MI.getParent()->getParent();
3991c3f7f17SFangrui Song   const TargetSubtargetInfo &STI = MF.getSubtarget();
4001c3f7f17SFangrui Song   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
4011c3f7f17SFangrui Song   const MachineRegisterInfo &MRI = MF.getRegInfo();
4021c3f7f17SFangrui Song 
4031c3f7f17SFangrui Song   switch (MI.getOpcode()) {
4041c3f7f17SFangrui Song   case TargetOpcode::G_LOAD:
4051c3f7f17SFangrui Song   case TargetOpcode::G_STORE:
4061c3f7f17SFangrui Song   case TargetOpcode::G_IMPLICIT_DEF: {
407564b81dbSMalaySanghiIntel     // we going to try to map 32/64/80 bit to PMI_FP32/PMI_FP64/PMI_FP80
4081c3f7f17SFangrui Song     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
409564b81dbSMalaySanghiIntel     if (Size != 32 && Size != 64 && Size != 80)
4101c3f7f17SFangrui Song       break;
4111c3f7f17SFangrui Song 
4121c3f7f17SFangrui Song     unsigned NumOperands = MI.getNumOperands();
4131c3f7f17SFangrui Song 
4141c3f7f17SFangrui Song     // Track the bank of each register, use FP mapping (all scalars in VEC)
4151c3f7f17SFangrui Song     SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
416564b81dbSMalaySanghiIntel     getInstrPartialMappingIdxs(MI, MRI, /* isFP= */ true, OpRegBankIdx);
4171c3f7f17SFangrui Song 
4181c3f7f17SFangrui Song     // Finally construct the computed mapping.
4191c3f7f17SFangrui Song     SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
4201c3f7f17SFangrui Song     if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
4211c3f7f17SFangrui Song       break;
4221c3f7f17SFangrui Song 
4231c3f7f17SFangrui Song     const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
4241c3f7f17SFangrui Song         /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands);
4251c3f7f17SFangrui Song     InstructionMappings AltMappings;
4261c3f7f17SFangrui Song     AltMappings.push_back(&Mapping);
4271c3f7f17SFangrui Song     return AltMappings;
4281c3f7f17SFangrui Song   }
4291c3f7f17SFangrui Song   default:
4301c3f7f17SFangrui Song     break;
4311c3f7f17SFangrui Song   }
4321c3f7f17SFangrui Song   return RegisterBankInfo::getInstrAlternativeMappings(MI);
4331c3f7f17SFangrui Song }
434