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