[llvm] 92c8052 - [MIPS GlobalISel] RegBankSelect G_MERGE_VALUES and G_UNMERGE_VALUES

Petar Avramovic via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 19 01:10:46 PST 2020


Author: Petar Avramovic
Date: 2020-02-19T10:09:52+01:00
New Revision: 92c80529ddb3ae147e9e58aed8d68b4aa2ea2379

URL: https://github.com/llvm/llvm-project/commit/92c80529ddb3ae147e9e58aed8d68b4aa2ea2379
DIFF: https://github.com/llvm/llvm-project/commit/92c80529ddb3ae147e9e58aed8d68b4aa2ea2379.diff

LOG: [MIPS GlobalISel] RegBankSelect G_MERGE_VALUES and G_UNMERGE_VALUES

Consider large operands in G_MERGE_VALUES and G_UNMERGE_VALUES as
Ambiguous during regbank selection.
Introducing new InstType AmbiguousWithMergeOrUnmerge which will
allow us to recognize whether to narrow scalar or use s64:fprb.

This change exposed a bug when reusing data from TypeInfoForMF.
Thus when Instr is about to get destroyed (using narrow scalar)
clear its data in TypeInfoForMF. Internal data is saved based on
Instr's address, and it will no longer be valid.
Add detailed asserts for InstType and operand size.

Generate generic instructions instead of MIPS target instructions
during argument lowering and custom legalizer.
Select G_UNMERGE_VALUES and G_MERGE_VALUES when proper banks are
selected: {s32:gprb, s32:gprb, s64:fprb} for G_UNMERGE_VALUES and
{s64:fprb, s32:gprb, s32:gprb} for G_MERGE_VALUES.
Update tests. One improvement is when floating point argument in
gpr(or two gprs) gets passed to another function through gpr
unnecessary fpr-to-gpr moves are no longer generated.

Differential Revision: https://reviews.llvm.org/D74623

Added: 
    

Modified: 
    llvm/lib/Target/Mips/MipsCallLowering.cpp
    llvm/lib/Target/Mips/MipsInstrFPU.td
    llvm/lib/Target/Mips/MipsInstructionSelector.cpp
    llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
    llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
    llvm/lib/Target/Mips/MipsRegisterBankInfo.h
    llvm/test/CodeGen/Mips/GlobalISel/instruction-select/float_args.mir
    llvm/test/CodeGen/Mips/GlobalISel/instruction-select/phi.mir
    llvm/test/CodeGen/Mips/GlobalISel/instruction-select/select.mir
    llvm/test/CodeGen/Mips/GlobalISel/instruction-select/sitofp_and_uitofp.mir
    llvm/test/CodeGen/Mips/GlobalISel/irtranslator/float_args.ll
    llvm/test/CodeGen/Mips/GlobalISel/legalizer/phi.mir
    llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir
    llvm/test/CodeGen/Mips/GlobalISel/legalizer/sitofp_and_uitofp.mir
    llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/float_args.ll
    llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll
    llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll
    llvm/test/CodeGen/Mips/GlobalISel/regbankselect/float_args.mir
    llvm/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir
    llvm/test/CodeGen/Mips/GlobalISel/regbankselect/select.mir
    llvm/test/CodeGen/Mips/GlobalISel/regbankselect/sitofp_and_uitofp.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp
index 115b5ae60b42..4d8d42eed00b 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp
@@ -136,29 +136,19 @@ class CallReturnHandler : public IncomingValueHandler {
 void IncomingValueHandler::assignValueToReg(Register ValVReg,
                                             const CCValAssign &VA,
                                             const EVT &VT) {
-  const MipsSubtarget &STI =
-      static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
   Register PhysReg = VA.getLocReg();
   if (VT == MVT::f64 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) {
     const MipsSubtarget &STI =
         static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
-
-    MIRBuilder
-        .buildInstr(STI.isFP64bit() ? Mips::BuildPairF64_64
-                                    : Mips::BuildPairF64)
-        .addDef(ValVReg)
-        .addUse(PhysReg + (STI.isLittle() ? 0 : 1))
-        .addUse(PhysReg + (STI.isLittle() ? 1 : 0))
-        .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
-                          *STI.getRegBankInfo());
+    bool IsEL = STI.isLittle();
+    LLT s32 = LLT::scalar(32);
+    auto Lo = MIRBuilder.buildCopy(s32, Register(PhysReg + (IsEL ? 0 : 1)));
+    auto Hi = MIRBuilder.buildCopy(s32, Register(PhysReg + (IsEL ? 1 : 0)));
+    MIRBuilder.buildMerge(ValVReg, {Lo, Hi});
     markPhysRegUsed(PhysReg);
     markPhysRegUsed(PhysReg + 1);
   } else if (VT == MVT::f32 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) {
-    MIRBuilder.buildInstr(Mips::MTC1)
-        .addDef(ValVReg)
-        .addUse(PhysReg)
-        .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
-                          *STI.getRegBankInfo());
+    MIRBuilder.buildCopy(ValVReg, PhysReg);
     markPhysRegUsed(PhysReg);
   } else {
     switch (VA.getLocInfo()) {
@@ -247,32 +237,15 @@ void OutgoingValueHandler::assignValueToReg(Register ValVReg,
                                             const CCValAssign &VA,
                                             const EVT &VT) {
   Register PhysReg = VA.getLocReg();
-  const MipsSubtarget &STI =
-      static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
-
   if (VT == MVT::f64 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) {
-    MIRBuilder
-        .buildInstr(STI.isFP64bit() ? Mips::ExtractElementF64_64
-                                    : Mips::ExtractElementF64)
-        .addDef(PhysReg + (STI.isLittle() ? 1 : 0))
-        .addUse(ValVReg)
-        .addImm(1)
-        .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
-                          *STI.getRegBankInfo());
-    MIRBuilder
-        .buildInstr(STI.isFP64bit() ? Mips::ExtractElementF64_64
-                                    : Mips::ExtractElementF64)
-        .addDef(PhysReg + (STI.isLittle() ? 0 : 1))
-        .addUse(ValVReg)
-        .addImm(0)
-        .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
-                          *STI.getRegBankInfo());
+    const MipsSubtarget &STI =
+        static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
+    bool IsEL = STI.isLittle();
+    auto Unmerge = MIRBuilder.buildUnmerge(LLT::scalar(32), ValVReg);
+    MIRBuilder.buildCopy(Register(PhysReg + (IsEL ? 0 : 1)), Unmerge.getReg(0));
+    MIRBuilder.buildCopy(Register(PhysReg + (IsEL ? 1 : 0)), Unmerge.getReg(1));
   } else if (VT == MVT::f32 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) {
-    MIRBuilder.buildInstr(Mips::MFC1)
-        .addDef(PhysReg)
-        .addUse(ValVReg)
-        .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
-                          *STI.getRegBankInfo());
+    MIRBuilder.buildCopy(PhysReg, ValVReg);
   } else {
     Register ExtReg = extendRegister(ValVReg, VA);
     MIRBuilder.buildCopy(PhysReg, ExtReg);

diff  --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td
index 79776998463f..d2f2b28376c9 100644
--- a/llvm/lib/Target/Mips/MipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MipsInstrFPU.td
@@ -48,6 +48,7 @@ def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond,
                           [SDNPHasChain, SDNPOptInGlue]>;
 def MipsTruncIntFP : SDNode<"MipsISD::TruncIntFP", SDT_MipsTruncIntFP>;
 def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>;
+def : GINodeEquiv<G_MERGE_VALUES, MipsBuildPairF64>;
 def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64",
                                    SDT_MipsExtractElementF64>;
 

diff  --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index 2f4c9d74262e..81acbb7adeee 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -472,6 +472,36 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
              .add(I.getOperand(3));
     break;
   }
+  case G_UNMERGE_VALUES: {
+    if (I.getNumOperands() != 3)
+      return false;
+    Register Src = I.getOperand(2).getReg();
+    Register Lo = I.getOperand(0).getReg();
+    Register Hi = I.getOperand(1).getReg();
+    if (!isRegInFprb(Src, MRI) ||
+        !(isRegInGprb(Lo, MRI) && isRegInGprb(Hi, MRI)))
+      return false;
+
+    unsigned Opcode =
+        STI.isFP64bit() ? Mips::ExtractElementF64_64 : Mips::ExtractElementF64;
+
+    MachineInstr *ExtractLo = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
+                                  .addDef(Lo)
+                                  .addUse(Src)
+                                  .addImm(0);
+    if (!constrainSelectedInstRegOperands(*ExtractLo, TII, TRI, RBI))
+      return false;
+
+    MachineInstr *ExtractHi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
+                                  .addDef(Hi)
+                                  .addUse(Src)
+                                  .addImm(1);
+    if (!constrainSelectedInstRegOperands(*ExtractHi, TII, TRI, RBI))
+      return false;
+
+    I.eraseFromParent();
+    return true;
+  }
   case G_IMPLICIT_DEF: {
     Register Dst = I.getOperand(0).getReg();
     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))

diff  --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index ecaa8ef30c67..d9309661efc3 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
@@ -283,8 +283,6 @@ bool MipsLegalizerInfo::legalizeCustom(MachineInstr &MI,
   using namespace TargetOpcode;
 
   MIRBuilder.setInstr(MI);
-  const MipsSubtarget &STI =
-      static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
   const LLT s32 = LLT::scalar(32);
   const LLT s64 = LLT::scalar(64);
 
@@ -307,11 +305,8 @@ bool MipsLegalizerInfo::legalizeCustom(MachineInstr &MI,
     // Next, subtract  2^52 * 0x1.0000000000000 i.e. 0x10000000000000.0 from it.
     // Done. Trunc double to float if needed.
 
-    MachineInstrBuilder Bitcast = MIRBuilder.buildInstr(
-        STI.isFP64bit() ? Mips::BuildPairF64_64 : Mips::BuildPairF64, {s64},
-        {Src, MIRBuilder.buildConstant(s32, UINT32_C(0x43300000))});
-    Bitcast.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
-                             *STI.getRegBankInfo());
+    auto C_HiMask = MIRBuilder.buildConstant(s32, UINT32_C(0x43300000));
+    auto Bitcast = MIRBuilder.buildMerge(s64, {Src, C_HiMask.getReg(0)});
 
     MachineInstrBuilder TwoP52FP = MIRBuilder.buildFConstant(
         s64, BitsToDouble(UINT64_C(0x4330000000000000)));

diff  --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index 754cc9406269..9f3c5d1853ad 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -132,9 +132,6 @@ static bool isFloatingPointOpcodeUse(unsigned Opc) {
   case TargetOpcode::G_FPTOSI:
   case TargetOpcode::G_FPTOUI:
   case TargetOpcode::G_FCMP:
-  case Mips::MFC1:
-  case Mips::ExtractElementF64:
-  case Mips::ExtractElementF64_64:
     return true;
   default:
     return isFloatingPointOpcode(Opc);
@@ -147,9 +144,6 @@ static bool isFloatingPointOpcodeDef(unsigned Opc) {
   switch (Opc) {
   case TargetOpcode::G_SITOFP:
   case TargetOpcode::G_UITOFP:
-  case Mips::MTC1:
-  case Mips::BuildPairF64:
-  case Mips::BuildPairF64_64:
     return true;
   default:
     return isFloatingPointOpcode(Opc);
@@ -163,6 +157,8 @@ static bool isAmbiguous(unsigned Opc) {
   case TargetOpcode::G_PHI:
   case TargetOpcode::G_SELECT:
   case TargetOpcode::G_IMPLICIT_DEF:
+  case TargetOpcode::G_UNMERGE_VALUES:
+  case TargetOpcode::G_MERGE_VALUES:
     return true;
   default:
     return false;
@@ -247,10 +243,17 @@ MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
 
   if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
     addDefUses(MI->getOperand(0).getReg(), MRI);
+
+  if (MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
+    addUseDef(MI->getOperand(MI->getNumOperands() - 1).getReg(), MRI);
+
+  if (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
+      addDefUses(MI->getOperand(0).getReg(), MRI);
 }
 
 bool MipsRegisterBankInfo::TypeInfoForMF::visit(
-    const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI) {
+    const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI,
+    InstType &AmbiguousTy) {
   assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
   if (wasVisited(MI))
     return true; // InstType has already been determined for MI.
@@ -258,18 +261,23 @@ bool MipsRegisterBankInfo::TypeInfoForMF::visit(
   startVisit(MI);
   AmbiguousRegDefUseContainer DefUseContainer(MI);
 
+  if (AmbiguousTy == InstType::Ambiguous &&
+      (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES ||
+       MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES))
+    AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge;
+
   // Visit instructions where MI's DEF operands are USED.
-  if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true))
+  if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true, AmbiguousTy))
     return true;
 
   // Visit instructions that DEFINE MI's USE operands.
-  if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false))
+  if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false, AmbiguousTy))
     return true;
 
   // All MI's adjacent instructions, are ambiguous.
   if (!WaitingForTypeOfMI) {
     // This is chain of ambiguous instructions.
-    setTypes(MI, InstType::Ambiguous);
+    setTypes(MI, AmbiguousTy);
     return true;
   }
   // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous
@@ -286,7 +294,7 @@ bool MipsRegisterBankInfo::TypeInfoForMF::visit(
 
 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
     const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
-    bool isDefUse) {
+    bool isDefUse, InstType &AmbiguousTy) {
   while (!AdjacentInstrs.empty()) {
     MachineInstr *AdjMI = AdjacentInstrs.pop_back_val();
 
@@ -303,9 +311,11 @@ bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
       return true;
     }
 
-    // Defaults to integer instruction. Includes G_MERGE_VALUES and
-    // G_UNMERGE_VALUES.
-    if (!isAmbiguous(AdjMI->getOpcode())) {
+    // Defaults to integer instruction. Small registers in G_MERGE (uses) and
+    // G_UNMERGE (defs) will always be gprb.
+    if ((!isDefUse && AdjMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) ||
+        (isDefUse && AdjMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) ||
+        !isAmbiguous(AdjMI->getOpcode())) {
       setTypes(MI, InstType::Integer);
       return true;
     }
@@ -314,7 +324,7 @@ bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
     // adjacent instructions and determine InstType without visiting AdjMI.
     if (!wasVisited(AdjMI) ||
         getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) {
-      if (visit(AdjMI, MI)) {
+      if (visit(AdjMI, MI, AmbiguousTy)) {
         // InstType is successfully determined and is same as for AdjMI.
         setTypes(MI, getRecordedTypeForInstr(AdjMI));
         return true;
@@ -355,7 +365,8 @@ void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
 
 MipsRegisterBankInfo::InstType
 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) {
-  visit(MI, nullptr);
+  InstType DefaultAmbiguousType = InstType::Ambiguous;
+  visit(MI, nullptr, DefaultAmbiguousType);
   return getRecordedTypeForInstr(MI);
 }
 
@@ -468,7 +479,7 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
       OperandsMapping = getMSAMapping(MF);
     break;
   case G_STORE:
-  case G_LOAD:
+  case G_LOAD: {
     if (Op0Size == 128) {
       OperandsMapping = getOperandsMapping(
           {getMSAMapping(MF), &Mips::ValueMappings[Mips::GPRIdx]});
@@ -478,41 +489,56 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     if (!Op0Ty.isPointer())
       InstTy = TI.determineInstType(&MI);
 
-    if (InstTy == InstType::FloatingPoint ||
-        (Op0Size == 64 && InstTy == InstType::Ambiguous))
+    if (isFloatingPoint_32or64(InstTy, Op0Size) ||
+        isAmbiguous_64(InstTy, Op0Size)) {
       OperandsMapping = getOperandsMapping(
           {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]});
-    else
+    } else {
+      assert((isInteger_32(InstTy, Op0Size) ||
+              isAmbiguous_32(InstTy, Op0Size) ||
+              isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
+             "Unexpected Inst type");
       OperandsMapping =
           getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID),
                               &Mips::ValueMappings[Mips::GPRIdx]});
+    }
 
     break;
-  case G_PHI:
+  }
+  case G_PHI: {
     if (!Op0Ty.isPointer())
       InstTy = TI.determineInstType(&MI);
 
     // PHI is copylike and should have one regbank in mapping for def register.
-    if (InstTy == InstType::Integer && Op0Size == 64) {
+    if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) {
       OperandsMapping =
           getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]});
+      TI.clearTypeInfoData(&MI);
       return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping,
                                    /*NumOperands=*/1);
     }
+    assert((isInteger_32(InstTy, Op0Size) ||
+            isFloatingPoint_32or64(InstTy, Op0Size) ||
+            isAmbiguous_32or64(InstTy, Op0Size)) &&
+           "Unexpected Inst type");
     // Use default handling for PHI, i.e. set reg bank of def operand to match
     // register banks of use operands.
     return getInstrMappingImpl(MI);
+  }
   case G_SELECT: {
     if (!Op0Ty.isPointer())
       InstTy = TI.determineInstType(&MI);
-
-    if (InstTy == InstType::FloatingPoint ||
-        (Op0Size == 64 && InstTy == InstType::Ambiguous)) {
+    if (isFloatingPoint_32or64(InstTy, Op0Size) ||
+        isAmbiguous_64(InstTy, Op0Size)) {
       const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size);
       OperandsMapping = getOperandsMapping(
           {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
       break;
     } else {
+      assert((isInteger_32(InstTy, Op0Size) ||
+              isAmbiguous_32(InstTy, Op0Size) ||
+              isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
+             "Unexpected Inst type");
       const RegisterBankInfo::ValueMapping *Bank =
           getGprbOrCustomMapping(Op0Size, MappingID);
       OperandsMapping = getOperandsMapping(
@@ -520,28 +546,45 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     }
     break;
   }
-  case G_IMPLICIT_DEF:
+  case G_IMPLICIT_DEF: {
     if (!Op0Ty.isPointer())
       InstTy = TI.determineInstType(&MI);
 
-    if (InstTy == InstType::FloatingPoint)
+    if (isFloatingPoint_32or64(InstTy, Op0Size))
       OperandsMapping = getFprbMapping(Op0Size);
-    else
+    else {
+      assert((isInteger_32(InstTy, Op0Size) ||
+              isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
+             "Unexpected Inst type");
       OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID);
-
-    break;
-  case G_UNMERGE_VALUES:
+    }
+  } break;
+  case G_UNMERGE_VALUES: {
+    assert(MI.getNumOperands() == 3 && "Unsupported G_UNMERGE_VALUES");
+    unsigned Op3Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
+    InstTy = TI.determineInstType(&MI);
+    assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size) ||
+            isFloatingPoint_64(InstTy, Op3Size)) &&
+           "Unexpected Inst type");
     OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
                                           &Mips::ValueMappings[Mips::GPRIdx],
                                           &Mips::ValueMappings[Mips::DPRIdx]});
-    MappingID = CustomMappingID;
+    if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size))
+      MappingID = CustomMappingID;
     break;
-  case G_MERGE_VALUES:
+  }
+  case G_MERGE_VALUES: {
+    InstTy = TI.determineInstType(&MI);
+    assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) ||
+            isFloatingPoint_64(InstTy, Op0Size)) &&
+           "Unexpected Inst type");
     OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx],
                                           &Mips::ValueMappings[Mips::GPRIdx],
                                           &Mips::ValueMappings[Mips::GPRIdx]});
-    MappingID = CustomMappingID;
+    if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size))
+      MappingID = CustomMappingID;
     break;
+  }
   case G_FADD:
   case G_FSUB:
   case G_FMUL:
@@ -606,6 +649,8 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     return getInvalidInstructionMapping();
   }
 
+  if (MappingID == CustomMappingID)
+    TI.clearTypeInfoData(&MI);
   return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping,
                                NumOperands);
 }

diff  --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
index 66267f8d794d..55eeaf096b14 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
@@ -66,9 +66,55 @@ class MipsRegisterBankInfo final : public MipsGenRegisterBankInfo {
     /// Represents moving 'bags of bits' around. Select same bank for entire
     /// chain to avoid cross bank copies. Currently we select fprb for s64 and
     /// gprb for s32 Ambiguous operands.
-    Ambiguous
+    Ambiguous,
+    /// Only used for s64. Unlike Ambiguous s64, AmbiguousWithMergeOrUnmerge s64
+    /// is mapped to gprb (legalized using narrow scalar to s32).
+    AmbiguousWithMergeOrUnmerge
   };
 
+  bool isAmbiguous_64(InstType InstTy, unsigned OpSize) const {
+    if (InstTy == InstType::Ambiguous && OpSize == 64)
+      return true;
+    return false;
+  }
+
+  bool isAmbiguous_32(InstType InstTy, unsigned OpSize) const {
+    if (InstTy == InstType::Ambiguous && OpSize == 32)
+      return true;
+    return false;
+  }
+
+  bool isAmbiguous_32or64(InstType InstTy, unsigned OpSize) const {
+    if (InstTy == InstType::Ambiguous && (OpSize == 32 || OpSize == 64))
+      return true;
+    return false;
+  }
+
+  bool isAmbiguousWithMergeOrUnmerge_64(InstType InstTy,
+                                        unsigned OpSize) const {
+    if (InstTy == InstType::AmbiguousWithMergeOrUnmerge && OpSize == 64)
+      return true;
+    return false;
+  }
+
+  bool isFloatingPoint_32or64(InstType InstTy, unsigned OpSize) const {
+    if (InstTy == InstType::FloatingPoint && (OpSize == 32 || OpSize == 64))
+      return true;
+    return false;
+  }
+
+  bool isFloatingPoint_64(InstType InstTy, unsigned OpSize) const {
+    if (InstTy == InstType::FloatingPoint && OpSize == 64)
+      return true;
+    return false;
+  }
+
+  bool isInteger_32(InstType InstTy, unsigned OpSize) const {
+    if (InstTy == InstType::Integer && OpSize == 32)
+      return true;
+    return false;
+  }
+
   /// Some generic instructions have operands that can be mapped to either fprb
   /// or gprb e.g. for G_LOAD we consider only operand 0 as ambiguous, operand 1
   /// is always gprb since it is a pointer.
@@ -113,12 +159,13 @@ class MipsRegisterBankInfo final : public MipsGenRegisterBankInfo {
     DenseMap<const MachineInstr *, InstType> Types;
 
     /// Recursively visit MI's adjacent instructions and find MI's InstType.
-    bool visit(const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI);
+    bool visit(const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI,
+               InstType &AmbiguousTy);
 
     /// Visit MI's adjacent UseDefs or DefUses.
     bool visitAdjacentInstrs(const MachineInstr *MI,
                              SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
-                             bool isDefUse);
+                             bool isDefUse, InstType &AmbiguousTy);
 
     /// Set type for MI, and recursively for all instructions that are
     /// waiting for MI's type.
@@ -170,6 +217,13 @@ class MipsRegisterBankInfo final : public MipsGenRegisterBankInfo {
     InstType determineInstType(const MachineInstr *MI);
 
     void cleanupIfNewFunction(llvm::StringRef FunctionName);
+
+    /// MI is about to get destroyed (using narrow scalar). Internal data is
+    /// saved based on MI's address, clear it since it is no longer valid.
+    void clearTypeInfoData(const MachineInstr *MI) {
+      Types.erase(MI);
+      WaitingQueues.erase(MI);
+    };
   };
 };
 } // end namespace llvm

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/float_args.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/float_args.mir
index 62d86990a3a3..226b42eebd05 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/float_args.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/float_args.mir
@@ -75,15 +75,15 @@ body:             |
 
     ; FP32-LABEL: name: float_in_gpr
     ; FP32: liveins: $a0, $a1
-    ; FP32: [[MTC1_:%[0-9]+]]:fgr32 = MTC1 $a1
-    ; FP32: $f0 = COPY [[MTC1_]]
+    ; FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a1
+    ; FP32: $f0 = COPY [[COPY]]
     ; FP32: RetRA implicit $f0
     ; FP64-LABEL: name: float_in_gpr
     ; FP64: liveins: $a0, $a1
-    ; FP64: [[MTC1_:%[0-9]+]]:fgr32 = MTC1 $a1
-    ; FP64: $f0 = COPY [[MTC1_]]
+    ; FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a1
+    ; FP64: $f0 = COPY [[COPY]]
     ; FP64: RetRA implicit $f0
-    %1:fgr32(s32) = MTC1 $a1
+    %1:gprb(s32) = COPY $a1
     $f0 = COPY %1(s32)
     RetRA implicit $f0
 
@@ -100,15 +100,21 @@ body:             |
 
     ; FP32-LABEL: name: double_in_gpr
     ; FP32: liveins: $a0, $a2, $a3
-    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64 = BuildPairF64 $a2, $a3
+    ; FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a2
+    ; FP32: [[COPY1:%[0-9]+]]:gpr32 = COPY $a3
+    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64 = BuildPairF64 [[COPY]], [[COPY1]]
     ; FP32: $d0 = COPY [[BuildPairF64_]]
     ; FP32: RetRA implicit $d0
     ; FP64-LABEL: name: double_in_gpr
     ; FP64: liveins: $a0, $a2, $a3
-    ; FP64: [[BuildPairF64_:%[0-9]+]]:afgr64 = BuildPairF64 $a2, $a3
-    ; FP64: $d0 = COPY [[BuildPairF64_]]
+    ; FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a2
+    ; FP64: [[COPY1:%[0-9]+]]:gpr32 = COPY $a3
+    ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64 = BuildPairF64_64 [[COPY]], [[COPY1]]
+    ; FP64: $d0 = COPY [[BuildPairF64_64_]]
     ; FP64: RetRA implicit $d0
-    %1:afgr64(s64) = BuildPairF64 $a2, $a3
+    %2:gprb(s32) = COPY $a2
+    %3:gprb(s32) = COPY $a3
+    %1:fprb(s64) = G_MERGE_VALUES %2(s32), %3(s32)
     $d0 = COPY %1(s64)
     RetRA implicit $d0
 
@@ -218,32 +224,32 @@ body:             |
     ; FP32-LABEL: name: call_float_in_gpr
     ; FP32: liveins: $a0, $a1
     ; FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
-    ; FP32: [[MTC1_:%[0-9]+]]:fgr32 = MTC1 $a1
+    ; FP32: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
     ; FP32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     ; FP32: $a0 = COPY [[COPY]]
-    ; FP32: $a1 = MFC1 [[MTC1_]]
+    ; FP32: $a1 = COPY [[COPY1]]
     ; FP32: JAL @float_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $f0
-    ; FP32: [[COPY1:%[0-9]+]]:fgr32 = COPY $f0
+    ; FP32: [[COPY2:%[0-9]+]]:fgr32 = COPY $f0
     ; FP32: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-    ; FP32: $f0 = COPY [[COPY1]]
+    ; FP32: $f0 = COPY [[COPY2]]
     ; FP32: RetRA implicit $f0
     ; FP64-LABEL: name: call_float_in_gpr
     ; FP64: liveins: $a0, $a1
     ; FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
-    ; FP64: [[MTC1_:%[0-9]+]]:fgr32 = MTC1 $a1
+    ; FP64: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
     ; FP64: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     ; FP64: $a0 = COPY [[COPY]]
-    ; FP64: $a1 = MFC1 [[MTC1_]]
+    ; FP64: $a1 = COPY [[COPY1]]
     ; FP64: JAL @float_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $f0
-    ; FP64: [[COPY1:%[0-9]+]]:fgr32 = COPY $f0
+    ; FP64: [[COPY2:%[0-9]+]]:fgr32 = COPY $f0
     ; FP64: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-    ; FP64: $f0 = COPY [[COPY1]]
+    ; FP64: $f0 = COPY [[COPY2]]
     ; FP64: RetRA implicit $f0
     %0:gprb(s32) = COPY $a0
-    %1:fgr32(s32) = MTC1 $a1
+    %1:gprb(s32) = COPY $a1
     ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     $a0 = COPY %0(s32)
-    $a1 = MFC1 %1(s32)
+    $a1 = COPY %1(s32)
     JAL @float_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $f0
     %2:fprb(s32) = COPY $f0
     ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
@@ -264,40 +270,42 @@ body:             |
     ; FP32-LABEL: name: call_double_in_gpr
     ; FP32: liveins: $a0, $a2, $a3
     ; FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
-    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64 = BuildPairF64 $a2, $a3
+    ; FP32: [[COPY1:%[0-9]+]]:gpr32 = COPY $a2
+    ; FP32: [[COPY2:%[0-9]+]]:gpr32 = COPY $a3
     ; FP32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     ; FP32: $a0 = COPY [[COPY]]
-    ; FP32: $a3 = ExtractElementF64 [[BuildPairF64_]], 1
-    ; FP32: $a2 = ExtractElementF64 [[BuildPairF64_]], 0
+    ; FP32: $a2 = COPY [[COPY1]]
+    ; FP32: $a3 = COPY [[COPY2]]
     ; FP32: JAL @double_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $d0
-    ; FP32: [[COPY1:%[0-9]+]]:afgr64 = COPY $d0
+    ; FP32: [[COPY3:%[0-9]+]]:afgr64 = COPY $d0
     ; FP32: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-    ; FP32: $d0 = COPY [[COPY1]]
+    ; FP32: $d0 = COPY [[COPY3]]
     ; FP32: RetRA implicit $d0
     ; FP64-LABEL: name: call_double_in_gpr
     ; FP64: liveins: $a0, $a2, $a3
     ; FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
-    ; FP64: [[BuildPairF64_:%[0-9]+]]:afgr64 = BuildPairF64 $a2, $a3
+    ; FP64: [[COPY1:%[0-9]+]]:gpr32 = COPY $a2
+    ; FP64: [[COPY2:%[0-9]+]]:gpr32 = COPY $a3
     ; FP64: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     ; FP64: $a0 = COPY [[COPY]]
-    ; FP64: $a3 = ExtractElementF64 [[BuildPairF64_]], 1
-    ; FP64: $a2 = ExtractElementF64 [[BuildPairF64_]], 0
+    ; FP64: $a2 = COPY [[COPY1]]
+    ; FP64: $a3 = COPY [[COPY2]]
     ; FP64: JAL @double_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $d0
-    ; FP64: [[COPY1:%[0-9]+]]:fgr64 = COPY $d0
+    ; FP64: [[COPY3:%[0-9]+]]:fgr64 = COPY $d0
     ; FP64: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-    ; FP64: $d0 = COPY [[COPY1]]
+    ; FP64: $d0 = COPY [[COPY3]]
     ; FP64: RetRA implicit $d0
     %0:gprb(s32) = COPY $a0
-    %1:afgr64(s64) = BuildPairF64 $a2, $a3
+    %2:gprb(s32) = COPY $a2
+    %3:gprb(s32) = COPY $a3
     ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     $a0 = COPY %0(s32)
-    $a3 = ExtractElementF64 %1(s64), 1
-    $a2 = ExtractElementF64 %1(s64), 0
+    $a2 = COPY %2(s32)
+    $a3 = COPY %3(s32)
     JAL @double_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $d0
-    %2:fprb(s64) = COPY $d0
+    %4:fprb(s64) = COPY $d0
     ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-    $d0 = COPY %2(s64)
+    $d0 = COPY %4(s64)
     RetRA implicit $d0
 
 ...
-

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/phi.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/phi.mir
index 07a03d1c4222..2be2092d0e67 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/phi.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/phi.mir
@@ -233,8 +233,8 @@ body:             |
   ; MIPS32FP32:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
   ; MIPS32FP32:   liveins: $a0, $a1, $a2
   ; MIPS32FP32:   [[COPY:%[0-9]+]]:gpr32 = COPY $a0
-  ; MIPS32FP32:   [[MTC1_:%[0-9]+]]:fgr32 = MTC1 $a1
-  ; MIPS32FP32:   [[MTC1_1:%[0-9]+]]:fgr32 = MTC1 $a2
+  ; MIPS32FP32:   [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+  ; MIPS32FP32:   [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
   ; MIPS32FP32:   [[ANDi:%[0-9]+]]:gpr32 = ANDi [[COPY]], 1
   ; MIPS32FP32:   BNE [[ANDi]], $zero, %bb.1, implicit-def $at
   ; MIPS32FP32:   J %bb.2, implicit-def $at
@@ -244,7 +244,7 @@ body:             |
   ; MIPS32FP32: bb.2.cond.false:
   ; MIPS32FP32:   successors: %bb.3(0x80000000)
   ; MIPS32FP32: bb.3.cond.end:
-  ; MIPS32FP32:   [[PHI:%[0-9]+]]:fgr32 = PHI [[MTC1_]], %bb.1, [[MTC1_1]], %bb.2
+  ; MIPS32FP32:   [[PHI:%[0-9]+]]:gpr32 = PHI [[COPY1]], %bb.1, [[COPY2]], %bb.2
   ; MIPS32FP32:   $f0 = COPY [[PHI]]
   ; MIPS32FP32:   RetRA implicit $f0
   ; MIPS32FP64-LABEL: name: phi_float
@@ -252,8 +252,8 @@ body:             |
   ; MIPS32FP64:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
   ; MIPS32FP64:   liveins: $a0, $a1, $a2
   ; MIPS32FP64:   [[COPY:%[0-9]+]]:gpr32 = COPY $a0
-  ; MIPS32FP64:   [[MTC1_:%[0-9]+]]:fgr32 = MTC1 $a1
-  ; MIPS32FP64:   [[MTC1_1:%[0-9]+]]:fgr32 = MTC1 $a2
+  ; MIPS32FP64:   [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+  ; MIPS32FP64:   [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
   ; MIPS32FP64:   [[ANDi:%[0-9]+]]:gpr32 = ANDi [[COPY]], 1
   ; MIPS32FP64:   BNE [[ANDi]], $zero, %bb.1, implicit-def $at
   ; MIPS32FP64:   J %bb.2, implicit-def $at
@@ -263,15 +263,15 @@ body:             |
   ; MIPS32FP64: bb.2.cond.false:
   ; MIPS32FP64:   successors: %bb.3(0x80000000)
   ; MIPS32FP64: bb.3.cond.end:
-  ; MIPS32FP64:   [[PHI:%[0-9]+]]:fgr32 = PHI [[MTC1_]], %bb.1, [[MTC1_1]], %bb.2
+  ; MIPS32FP64:   [[PHI:%[0-9]+]]:gpr32 = PHI [[COPY1]], %bb.1, [[COPY2]], %bb.2
   ; MIPS32FP64:   $f0 = COPY [[PHI]]
   ; MIPS32FP64:   RetRA implicit $f0
   bb.1.entry:
     liveins: $a0, $a1, $a2
 
     %3:gprb(s32) = COPY $a0
-    %1:fgr32(s32) = MTC1 $a1
-    %2:fgr32(s32) = MTC1 $a2
+    %1:gprb(s32) = COPY $a1
+    %2:gprb(s32) = COPY $a2
     %6:gprb(s32) = G_CONSTANT i32 1
     %7:gprb(s32) = COPY %3(s32)
     %5:gprb(s32) = G_AND %7, %6
@@ -284,7 +284,7 @@ body:             |
   bb.3.cond.false:
 
   bb.4.cond.end:
-    %4:fprb(s32) = G_PHI %1(s32), %bb.2, %2(s32), %bb.3
+    %4:gprb(s32) = G_PHI %1(s32), %bb.2, %2(s32), %bb.3
     $f0 = COPY %4(s32)
     RetRA implicit $f0
 

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/select.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/select.mir
index 84bd98c9b52e..fa4426f496a7 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/select.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/select.mir
@@ -100,28 +100,34 @@ body:             |
     ; MIPS32FP32-LABEL: name: select_float
     ; MIPS32FP32: liveins: $a0, $a1, $a2
     ; MIPS32FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
-    ; MIPS32FP32: [[MTC1_:%[0-9]+]]:fgr32 = MTC1 $a1
-    ; MIPS32FP32: [[MTC1_1:%[0-9]+]]:fgr32 = MTC1 $a2
+    ; MIPS32FP32: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+    ; MIPS32FP32: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
     ; MIPS32FP32: [[ANDi:%[0-9]+]]:gpr32 = ANDi [[COPY]], 1
-    ; MIPS32FP32: [[MOVN_I_S:%[0-9]+]]:fgr32 = MOVN_I_S [[MTC1_]], [[ANDi]], [[MTC1_1]]
+    ; MIPS32FP32: [[COPY3:%[0-9]+]]:fgr32 = COPY [[COPY1]]
+    ; MIPS32FP32: [[COPY4:%[0-9]+]]:fgr32 = COPY [[COPY2]]
+    ; MIPS32FP32: [[MOVN_I_S:%[0-9]+]]:fgr32 = MOVN_I_S [[COPY3]], [[ANDi]], [[COPY4]]
     ; MIPS32FP32: $f0 = COPY [[MOVN_I_S]]
     ; MIPS32FP32: RetRA implicit $f0
     ; MIPS32FP64-LABEL: name: select_float
     ; MIPS32FP64: liveins: $a0, $a1, $a2
     ; MIPS32FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
-    ; MIPS32FP64: [[MTC1_:%[0-9]+]]:fgr32 = MTC1 $a1
-    ; MIPS32FP64: [[MTC1_1:%[0-9]+]]:fgr32 = MTC1 $a2
+    ; MIPS32FP64: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+    ; MIPS32FP64: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
     ; MIPS32FP64: [[ANDi:%[0-9]+]]:gpr32 = ANDi [[COPY]], 1
-    ; MIPS32FP64: [[MOVN_I_S:%[0-9]+]]:fgr32 = MOVN_I_S [[MTC1_]], [[ANDi]], [[MTC1_1]]
+    ; MIPS32FP64: [[COPY3:%[0-9]+]]:fgr32 = COPY [[COPY1]]
+    ; MIPS32FP64: [[COPY4:%[0-9]+]]:fgr32 = COPY [[COPY2]]
+    ; MIPS32FP64: [[MOVN_I_S:%[0-9]+]]:fgr32 = MOVN_I_S [[COPY3]], [[ANDi]], [[COPY4]]
     ; MIPS32FP64: $f0 = COPY [[MOVN_I_S]]
     ; MIPS32FP64: RetRA implicit $f0
     %3:gprb(s32) = COPY $a0
-    %1:fgr32(s32) = MTC1 $a1
-    %2:fgr32(s32) = MTC1 $a2
+    %1:gprb(s32) = COPY $a1
+    %2:gprb(s32) = COPY $a2
     %6:gprb(s32) = G_CONSTANT i32 1
     %7:gprb(s32) = COPY %3(s32)
     %5:gprb(s32) = G_AND %7, %6
-    %4:fprb(s32) = G_SELECT %5(s32), %1, %2
+    %8:fprb(s32) = COPY %1(s32)
+    %9:fprb(s32) = COPY %2(s32)
+    %4:fprb(s32) = G_SELECT %5(s32), %8, %9
     $f0 = COPY %4(s32)
     RetRA implicit $f0
 

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/sitofp_and_uitofp.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/sitofp_and_uitofp.mir
index edeb3966d861..1569e00f3095 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/sitofp_and_uitofp.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/sitofp_and_uitofp.mir
@@ -5,6 +5,7 @@
 
   define void @i32tof32() {entry: ret void}
   define void @i32tof64() {entry: ret void}
+  define void @u32tof64() {entry: ret void}
 
 ...
 ---
@@ -63,3 +64,44 @@ body:             |
     RetRA implicit $d0
 
 ...
+---
+name:            u32tof64
+alignment:       4
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $a0
+
+    ; FP32-LABEL: name: u32tof64
+    ; FP32: liveins: $a0
+    ; FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+    ; FP32: [[LUi:%[0-9]+]]:gpr32 = LUi 17200
+    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64 = BuildPairF64 [[COPY]], [[LUi]]
+    ; FP32: [[LUi1:%[0-9]+]]:gpr32 = LUi 17200
+    ; FP32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 0
+    ; FP32: [[BuildPairF64_1:%[0-9]+]]:afgr64 = BuildPairF64 [[ORi]], [[LUi1]]
+    ; FP32: [[FSUB_D32_:%[0-9]+]]:afgr64 = FSUB_D32 [[BuildPairF64_]], [[BuildPairF64_1]]
+    ; FP32: $d0 = COPY [[FSUB_D32_]]
+    ; FP32: RetRA implicit $d0
+    ; FP64-LABEL: name: u32tof64
+    ; FP64: liveins: $a0
+    ; FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+    ; FP64: [[LUi:%[0-9]+]]:gpr32 = LUi 17200
+    ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64 = BuildPairF64_64 [[COPY]], [[LUi]]
+    ; FP64: [[LUi1:%[0-9]+]]:gpr32 = LUi 17200
+    ; FP64: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 0
+    ; FP64: [[BuildPairF64_64_1:%[0-9]+]]:fgr64 = BuildPairF64_64 [[ORi]], [[LUi1]]
+    ; FP64: [[FSUB_D64_:%[0-9]+]]:fgr64 = FSUB_D64 [[BuildPairF64_64_]], [[BuildPairF64_64_1]]
+    ; FP64: $d0 = COPY [[FSUB_D64_]]
+    ; FP64: RetRA implicit $d0
+    %0:gprb(s32) = COPY $a0
+    %2:gprb(s32) = G_CONSTANT i32 1127219200
+    %3:fprb(s64) = G_MERGE_VALUES %0(s32), %2(s32)
+    %4:fprb(s64) = G_FCONSTANT double 0x4330000000000000
+    %1:fprb(s64) = G_FSUB %3, %4
+    $d0 = COPY %1(s64)
+    RetRA implicit $d0
+
+...

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/float_args.ll b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/float_args.ll
index 24cfcd895a78..3b5d402a1a29 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/float_args.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/float_args.ll
@@ -46,15 +46,15 @@ define float @float_in_gpr(i32 %a, float %b) {
   ; FP32: bb.1.entry:
   ; FP32:   liveins: $a0, $a1
   ; FP32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
-  ; FP32:   [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
-  ; FP32:   $f0 = COPY [[MTC1_]](s32)
+  ; FP32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
+  ; FP32:   $f0 = COPY [[COPY1]](s32)
   ; FP32:   RetRA implicit $f0
   ; FP64-LABEL: name: float_in_gpr
   ; FP64: bb.1.entry:
   ; FP64:   liveins: $a0, $a1
   ; FP64:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
-  ; FP64:   [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
-  ; FP64:   $f0 = COPY [[MTC1_]](s32)
+  ; FP64:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
+  ; FP64:   $f0 = COPY [[COPY1]](s32)
   ; FP64:   RetRA implicit $f0
 entry:
   ret float %b
@@ -65,15 +65,19 @@ define double @double_in_gpr(i32 %a, double %b) {
   ; FP32: bb.1.entry:
   ; FP32:   liveins: $a0, $a2, $a3
   ; FP32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
-  ; FP32:   [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 $a2, $a3
-  ; FP32:   $d0 = COPY [[BuildPairF64_]](s64)
+  ; FP32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a2
+  ; FP32:   [[COPY2:%[0-9]+]]:_(s32) = COPY $a3
+  ; FP32:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+  ; FP32:   $d0 = COPY [[MV]](s64)
   ; FP32:   RetRA implicit $d0
   ; FP64-LABEL: name: double_in_gpr
   ; FP64: bb.1.entry:
   ; FP64:   liveins: $a0, $a2, $a3
   ; FP64:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
-  ; FP64:   [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 $a2, $a3
-  ; FP64:   $d0_64 = COPY [[BuildPairF64_64_]](s64)
+  ; FP64:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a2
+  ; FP64:   [[COPY2:%[0-9]+]]:_(s32) = COPY $a3
+  ; FP64:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+  ; FP64:   $d0_64 = COPY [[MV]](s64)
   ; FP64:   RetRA implicit $d0_64
 entry:
   ret double %b
@@ -148,27 +152,27 @@ define float @call_float_in_gpr(i32 %a, float %b) {
   ; FP32: bb.1.entry:
   ; FP32:   liveins: $a0, $a1
   ; FP32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
-  ; FP32:   [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
+  ; FP32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
   ; FP32:   ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
   ; FP32:   $a0 = COPY [[COPY]](s32)
-  ; FP32:   $a1 = MFC1 [[MTC1_]](s32)
+  ; FP32:   $a1 = COPY [[COPY1]](s32)
   ; FP32:   JAL @float_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $f0
-  ; FP32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $f0
+  ; FP32:   [[COPY2:%[0-9]+]]:_(s32) = COPY $f0
   ; FP32:   ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-  ; FP32:   $f0 = COPY [[COPY1]](s32)
+  ; FP32:   $f0 = COPY [[COPY2]](s32)
   ; FP32:   RetRA implicit $f0
   ; FP64-LABEL: name: call_float_in_gpr
   ; FP64: bb.1.entry:
   ; FP64:   liveins: $a0, $a1
   ; FP64:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
-  ; FP64:   [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
+  ; FP64:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
   ; FP64:   ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
   ; FP64:   $a0 = COPY [[COPY]](s32)
-  ; FP64:   $a1 = MFC1 [[MTC1_]](s32)
+  ; FP64:   $a1 = COPY [[COPY1]](s32)
   ; FP64:   JAL @float_in_gpr, csr_o32_fp64, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $f0
-  ; FP64:   [[COPY1:%[0-9]+]]:_(s32) = COPY $f0
+  ; FP64:   [[COPY2:%[0-9]+]]:_(s32) = COPY $f0
   ; FP64:   ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-  ; FP64:   $f0 = COPY [[COPY1]](s32)
+  ; FP64:   $f0 = COPY [[COPY2]](s32)
   ; FP64:   RetRA implicit $f0
 entry:
   %call = call float @float_in_gpr(i32 %a, float %b)
@@ -181,29 +185,35 @@ define double @call_double_in_gpr(i32 %a, double %b) {
   ; FP32: bb.1.entry:
   ; FP32:   liveins: $a0, $a2, $a3
   ; FP32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
-  ; FP32:   [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 $a2, $a3
+  ; FP32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a2
+  ; FP32:   [[COPY2:%[0-9]+]]:_(s32) = COPY $a3
+  ; FP32:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
   ; FP32:   ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
   ; FP32:   $a0 = COPY [[COPY]](s32)
-  ; FP32:   $a3 = ExtractElementF64 [[BuildPairF64_]](s64), 1
-  ; FP32:   $a2 = ExtractElementF64 [[BuildPairF64_]](s64), 0
+  ; FP32:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MV]](s64)
+  ; FP32:   $a2 = COPY [[UV]](s32)
+  ; FP32:   $a3 = COPY [[UV1]](s32)
   ; FP32:   JAL @double_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $d0
-  ; FP32:   [[COPY1:%[0-9]+]]:_(s64) = COPY $d0
+  ; FP32:   [[COPY3:%[0-9]+]]:_(s64) = COPY $d0
   ; FP32:   ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-  ; FP32:   $d0 = COPY [[COPY1]](s64)
+  ; FP32:   $d0 = COPY [[COPY3]](s64)
   ; FP32:   RetRA implicit $d0
   ; FP64-LABEL: name: call_double_in_gpr
   ; FP64: bb.1.entry:
   ; FP64:   liveins: $a0, $a2, $a3
   ; FP64:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
-  ; FP64:   [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 $a2, $a3
+  ; FP64:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a2
+  ; FP64:   [[COPY2:%[0-9]+]]:_(s32) = COPY $a3
+  ; FP64:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
   ; FP64:   ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
   ; FP64:   $a0 = COPY [[COPY]](s32)
-  ; FP64:   $a3 = ExtractElementF64_64 [[BuildPairF64_64_]](s64), 1
-  ; FP64:   $a2 = ExtractElementF64_64 [[BuildPairF64_64_]](s64), 0
+  ; FP64:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MV]](s64)
+  ; FP64:   $a2 = COPY [[UV]](s32)
+  ; FP64:   $a3 = COPY [[UV1]](s32)
   ; FP64:   JAL @double_in_gpr, csr_o32_fp64, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $d0_64
-  ; FP64:   [[COPY1:%[0-9]+]]:_(s64) = COPY $d0_64
+  ; FP64:   [[COPY3:%[0-9]+]]:_(s64) = COPY $d0_64
   ; FP64:   ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-  ; FP64:   $d0_64 = COPY [[COPY1]](s64)
+  ; FP64:   $d0_64 = COPY [[COPY3]](s64)
   ; FP64:   RetRA implicit $d0_64
 entry:
   %call = call double @double_in_gpr(i32 %a, double %b)

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/phi.mir b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/phi.mir
index 34d3f3e91601..e14c3a16b6b6 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/phi.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/phi.mir
@@ -77,6 +77,24 @@
     ret i64 %cond
   }
 
+  define void @phi_ambiguous_i64_in_fpr(i1 %cnd, i64* %i64_ptr_a, i64* %i64_ptr_b, i64* %i64_ptr_c) {
+  entry:
+    %0 = load i64, i64* %i64_ptr_a, align 8
+    %1 = load i64, i64* %i64_ptr_b, align 8
+    br i1 %cnd, label %cond.true, label %cond.false
+
+  cond.true:                                        ; preds = %entry
+    br label %cond.end
+
+  cond.false:                                       ; preds = %entry
+    br label %cond.end
+
+  cond.end:                                         ; preds = %cond.false, %cond.true
+    %cond = phi i64 [ %0, %cond.true ], [ %1, %cond.false ]
+    store i64 %cond, i64* %i64_ptr_c, align 8
+    ret void
+  }
+
   define float @phi_float(i1 %cnd, float %a, float %b) {
   entry:
     br i1 %cnd, label %cond.true, label %cond.false
@@ -92,6 +110,24 @@
     ret float %cond
   }
 
+  define void @phi_ambiguous_float_in_gpr(i1 %cnd, float* %f32_ptr_a, float* %f32_ptr_b, float* %f32_ptr_c) {
+  entry:
+    %0 = load float, float* %f32_ptr_a, align 4
+    %1 = load float, float* %f32_ptr_b, align 4
+    br i1 %cnd, label %cond.true, label %cond.false
+
+  cond.true:                                        ; preds = %entry
+    br label %cond.end
+
+  cond.false:                                       ; preds = %entry
+    br label %cond.end
+
+  cond.end:                                         ; preds = %cond.false, %cond.true
+    %cond = phi float [ %0, %cond.true ], [ %1, %cond.false ]
+    store float %cond, float* %f32_ptr_c, align 4
+    ret void
+  }
+
   define double @phi_double(double %a, double %b, i1 %cnd) {
   entry:
     br i1 %cnd, label %cond.true, label %cond.false
@@ -379,6 +415,59 @@ body:             |
     $v1 = COPY %12(s32)
     RetRA implicit $v0, implicit $v1
 
+...
+---
+name:            phi_ambiguous_i64_in_fpr
+alignment:       4
+tracksRegLiveness: true
+body:             |
+  ; MIPS32-LABEL: name: phi_ambiguous_i64_in_fpr
+  ; MIPS32: bb.0.entry:
+  ; MIPS32:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; MIPS32:   liveins: $a0, $a1, $a2, $a3
+  ; MIPS32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+  ; MIPS32:   [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
+  ; MIPS32:   [[COPY2:%[0-9]+]]:_(p0) = COPY $a2
+  ; MIPS32:   [[COPY3:%[0-9]+]]:_(p0) = COPY $a3
+  ; MIPS32:   [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[COPY1]](p0) :: (load 8 from %ir.i64_ptr_a)
+  ; MIPS32:   [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[COPY2]](p0) :: (load 8 from %ir.i64_ptr_b)
+  ; MIPS32:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+  ; MIPS32:   [[COPY4:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
+  ; MIPS32:   [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C]]
+  ; MIPS32:   G_BRCOND [[AND]](s32), %bb.1
+  ; MIPS32:   G_BR %bb.2
+  ; MIPS32: bb.1.cond.true:
+  ; MIPS32:   successors: %bb.3(0x80000000)
+  ; MIPS32:   G_BR %bb.3
+  ; MIPS32: bb.2.cond.false:
+  ; MIPS32:   successors: %bb.3(0x80000000)
+  ; MIPS32: bb.3.cond.end:
+  ; MIPS32:   [[PHI:%[0-9]+]]:_(s64) = G_PHI [[LOAD]](s64), %bb.1, [[LOAD1]](s64), %bb.2
+  ; MIPS32:   G_STORE [[PHI]](s64), [[COPY3]](p0) :: (store 8 into %ir.i64_ptr_c)
+  ; MIPS32:   RetRA
+  bb.1.entry:
+    liveins: $a0, $a1, $a2, $a3
+
+    %4:_(s32) = COPY $a0
+    %0:_(s1) = G_TRUNC %4(s32)
+    %1:_(p0) = COPY $a1
+    %2:_(p0) = COPY $a2
+    %3:_(p0) = COPY $a3
+    %5:_(s64) = G_LOAD %1(p0) :: (load 8 from %ir.i64_ptr_a)
+    %6:_(s64) = G_LOAD %2(p0) :: (load 8 from %ir.i64_ptr_b)
+    G_BRCOND %0(s1), %bb.2
+    G_BR %bb.3
+
+  bb.2.cond.true:
+    G_BR %bb.4
+
+  bb.3.cond.false:
+
+  bb.4.cond.end:
+    %7:_(s64) = G_PHI %5(s64), %bb.2, %6(s64), %bb.3
+    G_STORE %7(s64), %3(p0) :: (store 8 into %ir.i64_ptr_c)
+    RetRA
+
 ...
 ---
 name:            phi_float
@@ -390,11 +479,11 @@ body:             |
   ; MIPS32:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
   ; MIPS32:   liveins: $a0, $a1, $a2
   ; MIPS32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
-  ; MIPS32:   [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
-  ; MIPS32:   [[MTC1_1:%[0-9]+]]:fgr32(s32) = MTC1 $a2
+  ; MIPS32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
+  ; MIPS32:   [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
   ; MIPS32:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
-  ; MIPS32:   [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
-  ; MIPS32:   [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
+  ; MIPS32:   [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
+  ; MIPS32:   [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]]
   ; MIPS32:   G_BRCOND [[AND]](s32), %bb.1
   ; MIPS32:   G_BR %bb.2
   ; MIPS32: bb.1.cond.true:
@@ -403,7 +492,7 @@ body:             |
   ; MIPS32: bb.2.cond.false:
   ; MIPS32:   successors: %bb.3(0x80000000)
   ; MIPS32: bb.3.cond.end:
-  ; MIPS32:   [[PHI:%[0-9]+]]:_(s32) = G_PHI [[MTC1_]](s32), %bb.1, [[MTC1_1]](s32), %bb.2
+  ; MIPS32:   [[PHI:%[0-9]+]]:_(s32) = G_PHI [[COPY1]](s32), %bb.1, [[COPY2]](s32), %bb.2
   ; MIPS32:   $f0 = COPY [[PHI]](s32)
   ; MIPS32:   RetRA implicit $f0
   bb.1.entry:
@@ -411,8 +500,8 @@ body:             |
 
     %3:_(s32) = COPY $a0
     %0:_(s1) = G_TRUNC %3(s32)
-    %1:fgr32(s32) = MTC1 $a1
-    %2:fgr32(s32) = MTC1 $a2
+    %1:_(s32) = COPY $a1
+    %2:_(s32) = COPY $a2
     G_BRCOND %0(s1), %bb.2
     G_BR %bb.3
 
@@ -426,6 +515,59 @@ body:             |
     $f0 = COPY %4(s32)
     RetRA implicit $f0
 
+...
+---
+name:            phi_ambiguous_float_in_gpr
+alignment:       4
+tracksRegLiveness: true
+body:             |
+  ; MIPS32-LABEL: name: phi_ambiguous_float_in_gpr
+  ; MIPS32: bb.0.entry:
+  ; MIPS32:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; MIPS32:   liveins: $a0, $a1, $a2, $a3
+  ; MIPS32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+  ; MIPS32:   [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
+  ; MIPS32:   [[COPY2:%[0-9]+]]:_(p0) = COPY $a2
+  ; MIPS32:   [[COPY3:%[0-9]+]]:_(p0) = COPY $a3
+  ; MIPS32:   [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY1]](p0) :: (load 4 from %ir.f32_ptr_a)
+  ; MIPS32:   [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[COPY2]](p0) :: (load 4 from %ir.f32_ptr_b)
+  ; MIPS32:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+  ; MIPS32:   [[COPY4:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
+  ; MIPS32:   [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C]]
+  ; MIPS32:   G_BRCOND [[AND]](s32), %bb.1
+  ; MIPS32:   G_BR %bb.2
+  ; MIPS32: bb.1.cond.true:
+  ; MIPS32:   successors: %bb.3(0x80000000)
+  ; MIPS32:   G_BR %bb.3
+  ; MIPS32: bb.2.cond.false:
+  ; MIPS32:   successors: %bb.3(0x80000000)
+  ; MIPS32: bb.3.cond.end:
+  ; MIPS32:   [[PHI:%[0-9]+]]:_(s32) = G_PHI [[LOAD]](s32), %bb.1, [[LOAD1]](s32), %bb.2
+  ; MIPS32:   G_STORE [[PHI]](s32), [[COPY3]](p0) :: (store 4 into %ir.f32_ptr_c)
+  ; MIPS32:   RetRA
+  bb.1.entry:
+    liveins: $a0, $a1, $a2, $a3
+
+    %4:_(s32) = COPY $a0
+    %0:_(s1) = G_TRUNC %4(s32)
+    %1:_(p0) = COPY $a1
+    %2:_(p0) = COPY $a2
+    %3:_(p0) = COPY $a3
+    %5:_(s32) = G_LOAD %1(p0) :: (load 4 from %ir.f32_ptr_a)
+    %6:_(s32) = G_LOAD %2(p0) :: (load 4 from %ir.f32_ptr_b)
+    G_BRCOND %0(s1), %bb.2
+    G_BR %bb.3
+
+  bb.2.cond.true:
+    G_BR %bb.4
+
+  bb.3.cond.false:
+
+  bb.4.cond.end:
+    %7:_(s32) = G_PHI %5(s32), %bb.2, %6(s32), %bb.3
+    G_STORE %7(s32), %3(p0) :: (store 4 into %ir.f32_ptr_c)
+    RetRA
+
 ...
 ---
 name:            phi_double

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir
index 057abae4d819..6f46f151dc21 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir
@@ -230,18 +230,18 @@ body:             |
     ; MIPS32-LABEL: name: select_float
     ; MIPS32: liveins: $a0, $a1, $a2
     ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
-    ; MIPS32: [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
-    ; MIPS32: [[MTC1_1:%[0-9]+]]:fgr32(s32) = MTC1 $a2
+    ; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
+    ; MIPS32: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
     ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
-    ; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
-    ; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
-    ; MIPS32: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[AND]](s32), [[MTC1_]], [[MTC1_1]]
+    ; MIPS32: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
+    ; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]]
+    ; MIPS32: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY2]]
     ; MIPS32: $f0 = COPY [[SELECT]](s32)
     ; MIPS32: RetRA implicit $f0
     %3:_(s32) = COPY $a0
     %0:_(s1) = G_TRUNC %3(s32)
-    %1:fgr32(s32) = MTC1 $a1
-    %2:fgr32(s32) = MTC1 $a2
+    %1:_(s32) = COPY $a1
+    %2:_(s32) = COPY $a2
     %4:_(s32) = G_SELECT %0(s1), %1, %2
     $f0 = COPY %4(s32)
     RetRA implicit $f0

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/sitofp_and_uitofp.mir b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/sitofp_and_uitofp.mir
index 01793bdd62bc..2e049c4d3ea1 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/sitofp_and_uitofp.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/sitofp_and_uitofp.mir
@@ -343,21 +343,21 @@ body:             |
 
     ; FP32-LABEL: name: u32tof32
     ; FP32: liveins: $a0
-    ; FP32: [[COPY:%[0-9]+]]:gpr32(s32) = COPY $a0
-    ; FP32: [[C:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[COPY]](s32), [[C]](s32)
+    ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+    ; FP32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP32: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[C]](s32)
     ; FP32: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C1]]
+    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C1]]
     ; FP32: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64)
     ; FP32: $f0 = COPY [[FPTRUNC]](s32)
     ; FP32: RetRA implicit $f0
     ; FP64-LABEL: name: u32tof32
     ; FP64: liveins: $a0
-    ; FP64: [[COPY:%[0-9]+]]:gpr32(s32) = COPY $a0
-    ; FP64: [[C:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[COPY]](s32), [[C]](s32)
+    ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+    ; FP64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP64: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[C]](s32)
     ; FP64: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C1]]
+    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C1]]
     ; FP64: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64)
     ; FP64: $f0 = COPY [[FPTRUNC]](s32)
     ; FP64: RetRA implicit $f0
@@ -380,11 +380,11 @@ body:             |
     ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
     ; FP32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
     ; FP32: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
-    ; FP32: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]]
-    ; FP32: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[AND]](s32), [[C1]](s32)
+    ; FP32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
+    ; FP32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP32: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[AND]](s32), [[C1]](s32)
     ; FP32: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C2]]
+    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C2]]
     ; FP32: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64)
     ; FP32: $f0 = COPY [[FPTRUNC]](s32)
     ; FP32: RetRA implicit $f0
@@ -393,11 +393,11 @@ body:             |
     ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
     ; FP64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
     ; FP64: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
-    ; FP64: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]]
-    ; FP64: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[AND]](s32), [[C1]](s32)
+    ; FP64: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
+    ; FP64: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP64: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[AND]](s32), [[C1]](s32)
     ; FP64: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C2]]
+    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C2]]
     ; FP64: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64)
     ; FP64: $f0 = COPY [[FPTRUNC]](s32)
     ; FP64: RetRA implicit $f0
@@ -421,11 +421,11 @@ body:             |
     ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
     ; FP32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
     ; FP32: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
-    ; FP32: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]]
-    ; FP32: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[AND]](s32), [[C1]](s32)
+    ; FP32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
+    ; FP32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP32: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[AND]](s32), [[C1]](s32)
     ; FP32: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C2]]
+    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C2]]
     ; FP32: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64)
     ; FP32: $f0 = COPY [[FPTRUNC]](s32)
     ; FP32: RetRA implicit $f0
@@ -434,11 +434,11 @@ body:             |
     ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
     ; FP64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
     ; FP64: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
-    ; FP64: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]]
-    ; FP64: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[AND]](s32), [[C1]](s32)
+    ; FP64: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
+    ; FP64: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP64: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[AND]](s32), [[C1]](s32)
     ; FP64: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C2]]
+    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C2]]
     ; FP64: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64)
     ; FP64: $f0 = COPY [[FPTRUNC]](s32)
     ; FP64: RetRA implicit $f0
@@ -499,20 +499,20 @@ body:             |
 
     ; FP32-LABEL: name: u32tof64
     ; FP32: liveins: $a0
-    ; FP32: [[COPY:%[0-9]+]]:gpr32(s32) = COPY $a0
-    ; FP32: [[C:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[COPY]](s32), [[C]](s32)
+    ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+    ; FP32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP32: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[C]](s32)
     ; FP32: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C1]]
+    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C1]]
     ; FP32: $d0 = COPY [[FSUB]](s64)
     ; FP32: RetRA implicit $d0
     ; FP64-LABEL: name: u32tof64
     ; FP64: liveins: $a0
-    ; FP64: [[COPY:%[0-9]+]]:gpr32(s32) = COPY $a0
-    ; FP64: [[C:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[COPY]](s32), [[C]](s32)
+    ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+    ; FP64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP64: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[C]](s32)
     ; FP64: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C1]]
+    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C1]]
     ; FP64: $d0 = COPY [[FSUB]](s64)
     ; FP64: RetRA implicit $d0
     %0:_(s32) = COPY $a0
@@ -534,11 +534,11 @@ body:             |
     ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
     ; FP32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
     ; FP32: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
-    ; FP32: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]]
-    ; FP32: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[AND]](s32), [[C1]](s32)
+    ; FP32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
+    ; FP32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP32: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[AND]](s32), [[C1]](s32)
     ; FP32: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C2]]
+    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C2]]
     ; FP32: $d0 = COPY [[FSUB]](s64)
     ; FP32: RetRA implicit $d0
     ; FP64-LABEL: name: u16tof64
@@ -546,11 +546,11 @@ body:             |
     ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
     ; FP64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
     ; FP64: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
-    ; FP64: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]]
-    ; FP64: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[AND]](s32), [[C1]](s32)
+    ; FP64: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
+    ; FP64: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP64: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[AND]](s32), [[C1]](s32)
     ; FP64: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C2]]
+    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C2]]
     ; FP64: $d0 = COPY [[FSUB]](s64)
     ; FP64: RetRA implicit $d0
     %1:_(s32) = COPY $a0
@@ -573,11 +573,11 @@ body:             |
     ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
     ; FP32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
     ; FP32: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
-    ; FP32: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]]
-    ; FP32: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[AND]](s32), [[C1]](s32)
+    ; FP32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
+    ; FP32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP32: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[AND]](s32), [[C1]](s32)
     ; FP32: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C2]]
+    ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C2]]
     ; FP32: $d0 = COPY [[FSUB]](s64)
     ; FP32: RetRA implicit $d0
     ; FP64-LABEL: name: u8tof64
@@ -585,11 +585,11 @@ body:             |
     ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
     ; FP64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
     ; FP64: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
-    ; FP64: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]]
-    ; FP64: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200
-    ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[AND]](s32), [[C1]](s32)
+    ; FP64: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
+    ; FP64: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1127219200
+    ; FP64: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[AND]](s32), [[C1]](s32)
     ; FP64: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000
-    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C2]]
+    ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[MV]], [[C2]]
     ; FP64: $d0 = COPY [[FSUB]](s64)
     ; FP64: RetRA implicit $d0
     %1:_(s32) = COPY $a0

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/float_args.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/float_args.ll
index e46b7e64acd2..d327ecf27a5a 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/float_args.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/float_args.ll
@@ -93,8 +93,6 @@ define float @call_float_in_gpr(i32 %a, float %b) {
 ; MIPS32-NEXT:    .cfi_def_cfa_offset 24
 ; MIPS32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
 ; MIPS32-NEXT:    .cfi_offset 31, -4
-; MIPS32-NEXT:    mtc1 $5, $f0
-; MIPS32-NEXT:    mfc1 $5, $f0
 ; MIPS32-NEXT:    jal float_in_gpr
 ; MIPS32-NEXT:    nop
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -108,39 +106,18 @@ entry:
 
 
 define double @call_double_in_gpr(i32 %a, double %b) {
-; FP32-LABEL: call_double_in_gpr:
-; FP32:       # %bb.0: # %entry
-; FP32-NEXT:    addiu $sp, $sp, -24
-; FP32-NEXT:    .cfi_def_cfa_offset 24
-; FP32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; FP32-NEXT:    .cfi_offset 31, -4
-; FP32-NEXT:    mtc1 $6, $f0
-; FP32-NEXT:    mtc1 $7, $f1
-; FP32-NEXT:    mfc1 $7, $f1
-; FP32-NEXT:    mfc1 $6, $f0
-; FP32-NEXT:    jal double_in_gpr
-; FP32-NEXT:    nop
-; FP32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; FP32-NEXT:    addiu $sp, $sp, 24
-; FP32-NEXT:    jr $ra
-; FP32-NEXT:    nop
-;
-; FP64-LABEL: call_double_in_gpr:
-; FP64:       # %bb.0: # %entry
-; FP64-NEXT:    addiu $sp, $sp, -24
-; FP64-NEXT:    .cfi_def_cfa_offset 24
-; FP64-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; FP64-NEXT:    .cfi_offset 31, -4
-; FP64-NEXT:    mtc1 $6, $f0
-; FP64-NEXT:    mthc1 $7, $f0
-; FP64-NEXT:    mfhc1 $7, $f0
-; FP64-NEXT:    mfc1 $6, $f0
-; FP64-NEXT:    jal double_in_gpr
-; FP64-NEXT:    nop
-; FP64-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; FP64-NEXT:    addiu $sp, $sp, 24
-; FP64-NEXT:    jr $ra
-; FP64-NEXT:    nop
+; MIPS32-LABEL: call_double_in_gpr:
+; MIPS32:       # %bb.0: # %entry
+; MIPS32-NEXT:    addiu $sp, $sp, -24
+; MIPS32-NEXT:    .cfi_def_cfa_offset 24
+; MIPS32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    .cfi_offset 31, -4
+; MIPS32-NEXT:    jal double_in_gpr
+; MIPS32-NEXT:    nop
+; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    addiu $sp, $sp, 24
+; MIPS32-NEXT:    jr $ra
+; MIPS32-NEXT:    nop
 entry:
   %call = call double @double_in_gpr(i32 %a, double %b)
   ret double %call

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll
index 4facc766f009..a48eda23e9f1 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll
@@ -270,26 +270,25 @@ define float @phi_float(i1 %cnd, float %a, float %b) {
 ; MIPS32:       # %bb.0: # %entry
 ; MIPS32-NEXT:    addiu $sp, $sp, -16
 ; MIPS32-NEXT:    .cfi_def_cfa_offset 16
-; MIPS32-NEXT:    mtc1 $5, $f0
-; MIPS32-NEXT:    mtc1 $6, $f1
 ; MIPS32-NEXT:    andi $1, $4, 1
-; MIPS32-NEXT:    swc1 $f0, 12($sp) # 4-byte Folded Spill
-; MIPS32-NEXT:    swc1 $f1, 8($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    sw $5, 12($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    sw $6, 8($sp) # 4-byte Folded Spill
 ; MIPS32-NEXT:    bnez $1, $BB6_2
 ; MIPS32-NEXT:    nop
 ; MIPS32-NEXT:  # %bb.1: # %entry
 ; MIPS32-NEXT:    j $BB6_3
 ; MIPS32-NEXT:    nop
 ; MIPS32-NEXT:  $BB6_2: # %cond.true
-; MIPS32-NEXT:    lwc1 $f0, 12($sp) # 4-byte Folded Reload
-; MIPS32-NEXT:    swc1 $f0, 4($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    lw $1, 12($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    sw $1, 4($sp) # 4-byte Folded Spill
 ; MIPS32-NEXT:    j $BB6_4
 ; MIPS32-NEXT:    nop
 ; MIPS32-NEXT:  $BB6_3: # %cond.false
-; MIPS32-NEXT:    lwc1 $f0, 8($sp) # 4-byte Folded Reload
-; MIPS32-NEXT:    swc1 $f0, 4($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    lw $1, 8($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    sw $1, 4($sp) # 4-byte Folded Spill
 ; MIPS32-NEXT:  $BB6_4: # %cond.end
-; MIPS32-NEXT:    lwc1 $f0, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    lw $1, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    mtc1 $1, $f0
 ; MIPS32-NEXT:    addiu $sp, $sp, 16
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    nop

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll
index 71c3023ca153..7420a15cad3b 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll
@@ -115,9 +115,9 @@ entry:
 define float @select_float(i1 %test, float %a, float %b) {
 ; MIPS32-LABEL: select_float:
 ; MIPS32:       # %bb.0: # %entry
+; MIPS32-NEXT:    andi $1, $4, 1
 ; MIPS32-NEXT:    mtc1 $5, $f0
 ; MIPS32-NEXT:    mtc1 $6, $f1
-; MIPS32-NEXT:    andi $1, $4, 1
 ; MIPS32-NEXT:    movn.s $f1, $f0, $1
 ; MIPS32-NEXT:    mov.s $f0, $f1
 ; MIPS32-NEXT:    jr $ra

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/float_args.mir b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/float_args.mir
index bca5e826f8e2..7886a9dfa223 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/float_args.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/float_args.mir
@@ -73,15 +73,15 @@ body:             |
 
     ; FP32-LABEL: name: float_in_gpr
     ; FP32: liveins: $a0, $a1
-    ; FP32: [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
-    ; FP32: $f0 = COPY [[MTC1_]](s32)
+    ; FP32: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a1
+    ; FP32: $f0 = COPY [[COPY]](s32)
     ; FP32: RetRA implicit $f0
     ; FP64-LABEL: name: float_in_gpr
     ; FP64: liveins: $a0, $a1
-    ; FP64: [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
-    ; FP64: $f0 = COPY [[MTC1_]](s32)
+    ; FP64: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a1
+    ; FP64: $f0 = COPY [[COPY]](s32)
     ; FP64: RetRA implicit $f0
-    %1:fgr32(s32) = MTC1 $a1
+    %1:_(s32) = COPY $a1
     $f0 = COPY %1(s32)
     RetRA implicit $f0
 
@@ -97,15 +97,21 @@ body:             |
 
     ; FP32-LABEL: name: double_in_gpr
     ; FP32: liveins: $a0, $a2, $a3
-    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 $a2, $a3
-    ; FP32: $d0 = COPY [[BuildPairF64_]](s64)
+    ; FP32: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a2
+    ; FP32: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a3
+    ; FP32: [[MV:%[0-9]+]]:fprb(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+    ; FP32: $d0 = COPY [[MV]](s64)
     ; FP32: RetRA implicit $d0
     ; FP64-LABEL: name: double_in_gpr
     ; FP64: liveins: $a0, $a2, $a3
-    ; FP64: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 $a2, $a3
-    ; FP64: $d0 = COPY [[BuildPairF64_]](s64)
+    ; FP64: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a2
+    ; FP64: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a3
+    ; FP64: [[MV:%[0-9]+]]:fprb(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+    ; FP64: $d0 = COPY [[MV]](s64)
     ; FP64: RetRA implicit $d0
-    %1:afgr64(s64) = BuildPairF64 $a2, $a3
+    %2:_(s32) = COPY $a2
+    %3:_(s32) = COPY $a3
+    %1:_(s64) = G_MERGE_VALUES %2(s32), %3(s32)
     $d0 = COPY %1(s64)
     RetRA implicit $d0
 
@@ -212,32 +218,32 @@ body:             |
     ; FP32-LABEL: name: call_float_in_gpr
     ; FP32: liveins: $a0, $a1
     ; FP32: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
-    ; FP32: [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
+    ; FP32: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a1
     ; FP32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     ; FP32: $a0 = COPY [[COPY]](s32)
-    ; FP32: $a1 = MFC1 [[MTC1_]](s32)
+    ; FP32: $a1 = COPY [[COPY1]](s32)
     ; FP32: JAL @float_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $f0
-    ; FP32: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f0
+    ; FP32: [[COPY2:%[0-9]+]]:fprb(s32) = COPY $f0
     ; FP32: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-    ; FP32: $f0 = COPY [[COPY1]](s32)
+    ; FP32: $f0 = COPY [[COPY2]](s32)
     ; FP32: RetRA implicit $f0
     ; FP64-LABEL: name: call_float_in_gpr
     ; FP64: liveins: $a0, $a1
     ; FP64: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
-    ; FP64: [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
+    ; FP64: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a1
     ; FP64: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     ; FP64: $a0 = COPY [[COPY]](s32)
-    ; FP64: $a1 = MFC1 [[MTC1_]](s32)
+    ; FP64: $a1 = COPY [[COPY1]](s32)
     ; FP64: JAL @float_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $f0
-    ; FP64: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f0
+    ; FP64: [[COPY2:%[0-9]+]]:fprb(s32) = COPY $f0
     ; FP64: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-    ; FP64: $f0 = COPY [[COPY1]](s32)
+    ; FP64: $f0 = COPY [[COPY2]](s32)
     ; FP64: RetRA implicit $f0
     %0:_(s32) = COPY $a0
-    %1:fgr32(s32) = MTC1 $a1
+    %1:_(s32) = COPY $a1
     ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     $a0 = COPY %0(s32)
-    $a1 = MFC1 %1(s32)
+    $a1 = COPY %1(s32)
     JAL @float_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $f0
     %2:_(s32) = COPY $f0
     ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
@@ -257,40 +263,42 @@ body:             |
     ; FP32-LABEL: name: call_double_in_gpr
     ; FP32: liveins: $a0, $a2, $a3
     ; FP32: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
-    ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 $a2, $a3
+    ; FP32: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a2
+    ; FP32: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $a3
     ; FP32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     ; FP32: $a0 = COPY [[COPY]](s32)
-    ; FP32: $a3 = ExtractElementF64 [[BuildPairF64_]](s64), 1
-    ; FP32: $a2 = ExtractElementF64 [[BuildPairF64_]](s64), 0
+    ; FP32: $a2 = COPY [[COPY1]](s32)
+    ; FP32: $a3 = COPY [[COPY2]](s32)
     ; FP32: JAL @double_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $d0
-    ; FP32: [[COPY1:%[0-9]+]]:fprb(s64) = COPY $d0
+    ; FP32: [[COPY3:%[0-9]+]]:fprb(s64) = COPY $d0
     ; FP32: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-    ; FP32: $d0 = COPY [[COPY1]](s64)
+    ; FP32: $d0 = COPY [[COPY3]](s64)
     ; FP32: RetRA implicit $d0
     ; FP64-LABEL: name: call_double_in_gpr
     ; FP64: liveins: $a0, $a2, $a3
     ; FP64: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
-    ; FP64: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 $a2, $a3
+    ; FP64: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a2
+    ; FP64: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $a3
     ; FP64: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     ; FP64: $a0 = COPY [[COPY]](s32)
-    ; FP64: $a3 = ExtractElementF64 [[BuildPairF64_]](s64), 1
-    ; FP64: $a2 = ExtractElementF64 [[BuildPairF64_]](s64), 0
+    ; FP64: $a2 = COPY [[COPY1]](s32)
+    ; FP64: $a3 = COPY [[COPY2]](s32)
     ; FP64: JAL @double_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $d0
-    ; FP64: [[COPY1:%[0-9]+]]:fprb(s64) = COPY $d0
+    ; FP64: [[COPY3:%[0-9]+]]:fprb(s64) = COPY $d0
     ; FP64: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-    ; FP64: $d0 = COPY [[COPY1]](s64)
+    ; FP64: $d0 = COPY [[COPY3]](s64)
     ; FP64: RetRA implicit $d0
     %0:_(s32) = COPY $a0
-    %1:afgr64(s64) = BuildPairF64 $a2, $a3
+    %2:_(s32) = COPY $a2
+    %3:_(s32) = COPY $a3
     ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
     $a0 = COPY %0(s32)
-    $a3 = ExtractElementF64 %1(s64), 1
-    $a2 = ExtractElementF64 %1(s64), 0
+    $a2 = COPY %2(s32)
+    $a3 = COPY %3(s32)
     JAL @double_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $d0
-    %2:_(s64) = COPY $d0
+    %4:_(s64) = COPY $d0
     ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
-    $d0 = COPY %2(s64)
+    $d0 = COPY %4(s64)
     RetRA implicit $d0
 
 ...
-

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir
index 34167e8937f1..09d26f0b563d 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir
@@ -283,11 +283,11 @@ body:             |
   ; MIPS32:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
   ; MIPS32:   liveins: $a0, $a1, $a2
   ; MIPS32:   [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
-  ; MIPS32:   [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
-  ; MIPS32:   [[MTC1_1:%[0-9]+]]:fgr32(s32) = MTC1 $a2
+  ; MIPS32:   [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a1
+  ; MIPS32:   [[COPY2:%[0-9]+]]:gprb(s32) = COPY $a2
   ; MIPS32:   [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
-  ; MIPS32:   [[COPY1:%[0-9]+]]:gprb(s32) = COPY [[COPY]](s32)
-  ; MIPS32:   [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY1]], [[C]]
+  ; MIPS32:   [[COPY3:%[0-9]+]]:gprb(s32) = COPY [[COPY]](s32)
+  ; MIPS32:   [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY3]], [[C]]
   ; MIPS32:   G_BRCOND [[AND]](s32), %bb.1
   ; MIPS32:   G_BR %bb.2
   ; MIPS32: bb.1.cond.true:
@@ -296,15 +296,15 @@ body:             |
   ; MIPS32: bb.2.cond.false:
   ; MIPS32:   successors: %bb.3(0x80000000)
   ; MIPS32: bb.3.cond.end:
-  ; MIPS32:   [[PHI:%[0-9]+]]:fprb(s32) = G_PHI [[MTC1_]](s32), %bb.1, [[MTC1_1]](s32), %bb.2
+  ; MIPS32:   [[PHI:%[0-9]+]]:gprb(s32) = G_PHI [[COPY1]](s32), %bb.1, [[COPY2]](s32), %bb.2
   ; MIPS32:   $f0 = COPY [[PHI]](s32)
   ; MIPS32:   RetRA implicit $f0
   bb.1.entry:
     liveins: $a0, $a1, $a2
 
     %3:_(s32) = COPY $a0
-    %1:fgr32(s32) = MTC1 $a1
-    %2:fgr32(s32) = MTC1 $a2
+    %1:_(s32) = COPY $a1
+    %2:_(s32) = COPY $a2
     %6:_(s32) = G_CONSTANT i32 1
     %7:_(s32) = COPY %3(s32)
     %5:_(s32) = G_AND %7, %6

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/select.mir b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/select.mir
index 6c1761c6ad2a..a9554968aaed 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/select.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/select.mir
@@ -170,17 +170,19 @@ body:             |
     ; MIPS32-LABEL: name: select_float
     ; MIPS32: liveins: $a0, $a1, $a2
     ; MIPS32: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
-    ; MIPS32: [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
-    ; MIPS32: [[MTC1_1:%[0-9]+]]:fgr32(s32) = MTC1 $a2
+    ; MIPS32: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a1
+    ; MIPS32: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $a2
     ; MIPS32: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
-    ; MIPS32: [[COPY1:%[0-9]+]]:gprb(s32) = COPY [[COPY]](s32)
-    ; MIPS32: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY1]], [[C]]
-    ; MIPS32: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s32), [[MTC1_]], [[MTC1_1]]
+    ; MIPS32: [[COPY3:%[0-9]+]]:gprb(s32) = COPY [[COPY]](s32)
+    ; MIPS32: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY3]], [[C]]
+    ; MIPS32: [[COPY4:%[0-9]+]]:fprb(s32) = COPY [[COPY1]](s32)
+    ; MIPS32: [[COPY5:%[0-9]+]]:fprb(s32) = COPY [[COPY2]](s32)
+    ; MIPS32: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s32), [[COPY4]], [[COPY5]]
     ; MIPS32: $f0 = COPY [[SELECT]](s32)
     ; MIPS32: RetRA implicit $f0
     %3:_(s32) = COPY $a0
-    %1:fgr32(s32) = MTC1 $a1
-    %2:fgr32(s32) = MTC1 $a2
+    %1:_(s32) = COPY $a1
+    %2:_(s32) = COPY $a2
     %6:_(s32) = G_CONSTANT i32 1
     %7:_(s32) = COPY %3(s32)
     %5:_(s32) = G_AND %7, %6

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/sitofp_and_uitofp.mir b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/sitofp_and_uitofp.mir
index 2d5b7991dbf8..dd9b05487dca 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/sitofp_and_uitofp.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/sitofp_and_uitofp.mir
@@ -5,6 +5,7 @@
 
   define void @i32tof32() {entry: ret void}
   define void @i32tof64() {entry: ret void}
+  define void @u32tof64() {entry: ret void}
 
 ...
 ---
@@ -61,3 +62,39 @@ body:             |
     RetRA implicit $d0
 
 ...
+---
+name:            u32tof64
+alignment:       4
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $a0
+
+    ; FP32-LABEL: name: u32tof64
+    ; FP32: liveins: $a0
+    ; FP32: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
+    ; FP32: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1127219200
+    ; FP32: [[MV:%[0-9]+]]:fprb(s64) = G_MERGE_VALUES [[COPY]](s32), [[C]](s32)
+    ; FP32: [[C1:%[0-9]+]]:fprb(s64) = G_FCONSTANT double 0x4330000000000000
+    ; FP32: [[FSUB:%[0-9]+]]:fprb(s64) = G_FSUB [[MV]], [[C1]]
+    ; FP32: $d0 = COPY [[FSUB]](s64)
+    ; FP32: RetRA implicit $d0
+    ; FP64-LABEL: name: u32tof64
+    ; FP64: liveins: $a0
+    ; FP64: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
+    ; FP64: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1127219200
+    ; FP64: [[MV:%[0-9]+]]:fprb(s64) = G_MERGE_VALUES [[COPY]](s32), [[C]](s32)
+    ; FP64: [[C1:%[0-9]+]]:fprb(s64) = G_FCONSTANT double 0x4330000000000000
+    ; FP64: [[FSUB:%[0-9]+]]:fprb(s64) = G_FSUB [[MV]], [[C1]]
+    ; FP64: $d0 = COPY [[FSUB]](s64)
+    ; FP64: RetRA implicit $d0
+    %0:_(s32) = COPY $a0
+    %2:_(s32) = G_CONSTANT i32 1127219200
+    %3:_(s64) = G_MERGE_VALUES %0(s32), %2(s32)
+    %4:_(s64) = G_FCONSTANT double 0x4330000000000000
+    %1:_(s64) = G_FSUB %3, %4
+    $d0 = COPY %1(s64)
+    RetRA implicit $d0
+
+...


        


More information about the llvm-commits mailing list