Revert "[mips] Promote the result of SETCC nodes to GPR width."

This reverts commit r262316.

It seems that my change breaks an out-of-tree chromium buildbot, so
I'm reverting this in order to investigate the situation further.

llvm-svn: 262387
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index 05228bb..ca149a1 100644
--- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -124,13 +124,9 @@
                                            uint64_t Address,
                                            const void *Decoder);
 
-static DecodeStatus DecodeFGRCC32RegisterClass(MCInst &Inst, unsigned RegNo,
-                                               uint64_t Address,
-                                               const void *Decoder);
-
-static DecodeStatus DecodeFGRCC64RegisterClass(MCInst &Inst, unsigned RegNo,
-                                               uint64_t Address,
-                                               const void *Decoder);
+static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
+                                             uint64_t Address,
+                                             const void *Decoder);
 
 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
                                               unsigned Insn,
@@ -902,17 +898,6 @@
     if (Result == MCDisassembler::Fail)
       return MCDisassembler::Fail;
 
-    if (hasMips32r6() && isGP64()) {
-      DEBUG(dbgs() << "Trying MicroMipsR6_GP64 table (32-bit instructions):\n");
-      // Calling the auto-generated decoder function.
-      Result = decodeInstruction(DecoderTableMicroMipsR6_GP6432, Instr, Insn,
-                                 Address, this, STI);
-      if (Result != MCDisassembler::Fail) {
-        Size = 4;
-        return Result;
-      }
-    }
-
     if (hasMips32r6()) {
       DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
       // Calling the auto-generated decoder function.
@@ -955,9 +940,9 @@
   }
 
   if (hasMips32r6() && isGP64()) {
-    DEBUG(dbgs() << "Trying Mips64r6 (GPR64) table (32-bit opcodes):\n");
-    Result = decodeInstruction(DecoderTableMips64r632, Instr, Insn, Address,
-                               this, STI);
+    DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
+    Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
+                               Address, this, STI);
     if (Result != MCDisassembler::Fail) {
       Size = 4;
       return Result;
@@ -1136,24 +1121,13 @@
   return MCDisassembler::Success;
 }
 
-static DecodeStatus DecodeFGRCC32RegisterClass(MCInst &Inst, unsigned RegNo,
-                                               uint64_t Address,
-                                               const void *Decoder) {
+static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
+                                             uint64_t Address,
+                                             const void *Decoder) {
   if (RegNo > 31)
     return MCDisassembler::Fail;
 
-  unsigned Reg = getReg(Decoder, Mips::FGRCC32RegClassID, RegNo);
-  Inst.addOperand(MCOperand::createReg(Reg));
-  return MCDisassembler::Success;
-}
-
-static DecodeStatus DecodeFGRCC64RegisterClass(MCInst &Inst, unsigned RegNo,
-                                               uint64_t Address,
-                                               const void *Decoder) {
-  if (RegNo > 31)
-    return MCDisassembler::Fail;
-
-  unsigned Reg = getReg(Decoder, Mips::FGRCC64RegClassID, RegNo);
+  unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
   Inst.addOperand(MCOperand::createReg(Reg));
   return MCDisassembler::Success;
 }
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
index cf68a6b..4286c36 100644
--- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
@@ -634,71 +634,71 @@
                                              II_CVT>, FGR_64;
 
 multiclass CMP_CC_MMR6<bits<6> format, string Typestr,
-                       RegisterOperand FGRCCOpnd, RegisterOperand FGROpnd> {
+                       RegisterOperand FGROpnd> {
   def CMP_AF_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.af.", Typestr), format, FIELD_CMP_COND_AF>,
-      CMP_CONDN_DESC_BASE<"af", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"af", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_UN_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.un.", Typestr), format, FIELD_CMP_COND_UN>,
-      CMP_CONDN_DESC_BASE<"un", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"un", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_EQ_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.eq.", Typestr), format, FIELD_CMP_COND_EQ>,
-      CMP_CONDN_DESC_BASE<"eq", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"eq", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_UEQ_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.ueq.", Typestr), format, FIELD_CMP_COND_UEQ>,
-      CMP_CONDN_DESC_BASE<"ueq", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"ueq", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_LT_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.lt.", Typestr), format, FIELD_CMP_COND_LT>,
-      CMP_CONDN_DESC_BASE<"lt", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"lt", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_ULT_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.ult.", Typestr), format, FIELD_CMP_COND_ULT>,
-      CMP_CONDN_DESC_BASE<"ult", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"ult", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_LE_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.le.", Typestr), format, FIELD_CMP_COND_LE>,
-      CMP_CONDN_DESC_BASE<"le", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"le", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_ULE_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.ule.", Typestr), format, FIELD_CMP_COND_ULE>,
-      CMP_CONDN_DESC_BASE<"ule", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"ule", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_SAF_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.saf.", Typestr), format, FIELD_CMP_COND_SAF>,
-      CMP_CONDN_DESC_BASE<"saf", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"saf", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_SUN_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.sun.", Typestr), format, FIELD_CMP_COND_SUN>,
-      CMP_CONDN_DESC_BASE<"sun", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"sun", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_SEQ_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.seq.", Typestr), format, FIELD_CMP_COND_SEQ>,
-      CMP_CONDN_DESC_BASE<"seq", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"seq", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_SUEQ_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.sueq.", Typestr), format, FIELD_CMP_COND_SUEQ>,
-      CMP_CONDN_DESC_BASE<"sueq", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"sueq", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_SLT_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.slt.", Typestr), format, FIELD_CMP_COND_SLT>,
-      CMP_CONDN_DESC_BASE<"slt", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"slt", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_SULT_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.sult.", Typestr), format, FIELD_CMP_COND_SULT>,
-      CMP_CONDN_DESC_BASE<"sult", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"sult", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_SLE_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.sle.", Typestr), format, FIELD_CMP_COND_SLE>,
-      CMP_CONDN_DESC_BASE<"sle", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"sle", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
   def CMP_SULE_#NAME : POOL32F_CMP_FM<
       !strconcat("cmp.sule.", Typestr), format, FIELD_CMP_COND_SULE>,
-      CMP_CONDN_DESC_BASE<"sule", Typestr, FGRCCOpnd, FGROpnd>,
-      HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6;
+      CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel,
+      ISA_MICROMIPS32R6;
 }
 
 class ABSS_FT_MMR6_DESC_BASE<string instr_asm, RegisterOperand DstRC,
@@ -763,8 +763,8 @@
 class ROUND_W_D_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"round.w.d", FGR64Opnd,
                                                    FGR64Opnd, II_ROUND>;
 
-class SEL_S_MMR6_DESC : COP1_SEL_DESC_BASE<"sel.s", FGRCC32Opnd, FGR32Opnd>;
-class SEL_D_MMR6_DESC : COP1_SEL_DESC_BASE<"sel.d", FGRCC32Opnd, FGR64Opnd> {
+class SEL_S_MMR6_DESC : COP1_SEL_DESC_BASE<"sel.s", FGR32Opnd>;
+class SEL_D_MMR6_DESC : COP1_SEL_DESC_BASE<"sel.d", FGR64Opnd> {
   // We must insert a SUBREG_TO_REG around $fd_in
   bit usesCustomInserter = 1;
 }
@@ -1115,8 +1115,8 @@
                    ISA_MICROMIPS32R6;
 def CVT_S_L_MMR6 : StdMMR6Rel, CVT_S_L_MMR6_ENC, CVT_S_L_MMR6_DESC,
                    ISA_MICROMIPS32R6;
-defm S_MMR6 : CMP_CC_MMR6<0b000101, "s", FGRCC32Opnd, FGR32Opnd>;
-defm D_MMR6 : CMP_CC_MMR6<0b010101, "d", FGRCC32Opnd, FGR64Opnd>;
+defm S_MMR6 : CMP_CC_MMR6<0b000101, "s", FGR32Opnd>;
+defm D_MMR6 : CMP_CC_MMR6<0b010101, "d", FGR64Opnd>;
 def ABS_S_MMR6 : StdMMR6Rel, ABS_S_MMR6_ENC, ABS_S_MMR6_DESC, ISA_MICROMIPS32R6;
 def ABS_D_MMR6 : StdMMR6Rel, ABS_D_MMR6_ENC, ABS_D_MMR6_DESC, ISA_MICROMIPS32R6;
 def FLOOR_L_S_MMR6 : StdMMR6Rel, FLOOR_L_S_MMR6_ENC, FLOOR_L_S_MMR6_DESC,
@@ -1200,10 +1200,8 @@
                      ISA_MICROMIPS32R6;
 def ROUND_W_D_MMR6 : StdMMR6Rel, ROUND_W_D_MMR6_ENC, ROUND_W_D_MMR6_DESC,
                      ISA_MICROMIPS32R6;
-def SEL_S_MMR6 : StdMMR6Rel, SEL_S_MMR6_ENC, SEL_S_MMR6_DESC, ISA_MICROMIPS32R6,
-                 HARDFLOAT;
-def SEL_D_MMR6 : StdMMR6Rel, SEL_D_MMR6_ENC, SEL_D_MMR6_DESC, ISA_MICROMIPS32R6,
-                 HARDFLOAT;
+def SEL_S_MMR6 : StdMMR6Rel, SEL_S_MMR6_ENC, SEL_S_MMR6_DESC, ISA_MICROMIPS32R6;
+def SEL_D_MMR6 : StdMMR6Rel, SEL_D_MMR6_ENC, SEL_D_MMR6_DESC, ISA_MICROMIPS32R6;
 def SELEQZ_S_MMR6 : StdMMR6Rel, SELEQZ_S_MMR6_ENC, SELEQZ_S_MMR6_DESC,
                     ISA_MICROMIPS32R6;
 def SELEQZ_D_MMR6 : StdMMR6Rel, SELEQZ_D_MMR6_ENC, SELEQZ_D_MMR6_DESC,
diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td
index 29337e4..96cbd10 100644
--- a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td
@@ -99,12 +99,6 @@
 class DINS_MM64R6_DESC : InsBase<"dins", GPR64Opnd, uimm5, uimm5_inssize_plus1,
                                  MipsIns>;
 
-class SEL_S_MM64R6_DESC : COP1_SEL_DESC_BASE<"sel.s", FGRCC64Opnd, FGR32Opnd> {
-  // We must copy FGRCC64Opnd's subreg into FGR32.
-  bit usesCustomInserter = 1;
-}
-class SEL_D_MM64R6_DESC : COP1_SEL_DESC_BASE<"sel.d", FGRCC64Opnd, FGR64Opnd>;
-
 //===----------------------------------------------------------------------===//
 //
 // Instruction Definitions
@@ -138,10 +132,3 @@
   def DINS_MM64R6: R6MMR6Rel, DINS_MM64R6_DESC, DINS_MM64R6_ENC,
                    ISA_MICROMIPS64R6;
 }
-
-let DecoderNamespace = "MicroMipsR6_GP64" in {
-def SEL_S_MM64R6 : StdMMR6Rel, SEL_S_MMR6_ENC, SEL_S_MM64R6_DESC,
-                   ISA_MICROMIPS64R6, HARDFLOAT;
-def SEL_D_MM64R6 : StdMMR6Rel, SEL_D_MMR6_ENC, SEL_D_MM64R6_DESC,
-                   ISA_MICROMIPS64R6, HARDFLOAT;
-}
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
index 97ec9f1..0519bf4 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
@@ -671,10 +671,10 @@
                  ADDI_FM_MM<0xc>;
   def ADDi_MM  : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>,
                  ADDI_FM_MM<0x4>;
-  def SLTi_MM  : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd,
-                                GPR32Opnd>, SLTI_FM_MM<0x24>;
-  def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd,
-                                GPR32Opnd>, SLTI_FM_MM<0x2c>;
+  def SLTi_MM  : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
+                 SLTI_FM_MM<0x24>;
+  def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
+                 SLTI_FM_MM<0x2c>;
   def ANDi_MM  : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd>,
                  ADDI_FM_MM<0x34>;
   def ORi_MM   : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd>,
@@ -694,9 +694,8 @@
   def MUL_MM   : MMRel, ArithLogicR<"mul", GPR32Opnd>, ADD_FM_MM<0, 0x210>;
   def ADD_MM   : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM_MM<0, 0x110>;
   def SUB_MM   : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM_MM<0, 0x190>;
-  def SLT_MM   : MMRel, SetCC_R<"slt", setlt, GPR32Opnd, GPR32Opnd>,
-                 ADD_FM_MM<0, 0x350>;
-  def SLTu_MM  : MMRel, SetCC_R<"sltu", setult, GPR32Opnd, GPR32Opnd>,
+  def SLT_MM   : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM_MM<0, 0x350>;
+  def SLTu_MM  : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>,
                  ADD_FM_MM<0, 0x390>;
   def AND_MM   : MMRel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
                  ADD_FM_MM<0, 0x250>;
diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
index 7723e88..82d2c8e 100644
--- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
@@ -176,7 +176,7 @@
 //===----------------------------------------------------------------------===//
 
 class CMP_CONDN_DESC_BASE<string CondStr, string Typestr,
-                          RegisterOperand FGRCCOpnd, RegisterOperand FGROpnd,
+                          RegisterOperand FGROpnd,
                           SDPatternOperator Op = null_frag> {
   dag OutOperandList = (outs FGRCCOpnd:$fd);
   dag InOperandList = (ins FGROpnd:$fs, FGROpnd:$ft);
@@ -184,58 +184,58 @@
   list<dag> Pattern = [(set FGRCCOpnd:$fd, (Op FGROpnd:$fs, FGROpnd:$ft))];
 }
 
-multiclass CMP_CC_M<FIELD_CMP_FORMAT Format, string Typestr,
-                    RegisterOperand FGRCCOpnd, RegisterOperand FGROpnd>{
-let AdditionalPredicates = [NotInMicroMips] in {
-def CMP_F_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_AF>,
-                  CMP_CONDN_DESC_BASE<"af", Typestr, FGRCCOpnd, FGROpnd>,
-                  ISA_MIPS32R6, HARDFLOAT;
-def CMP_UN_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_UN>,
-                   CMP_CONDN_DESC_BASE<"un", Typestr, FGRCCOpnd, FGROpnd,
-                                       setuo>, ISA_MIPS32R6, HARDFLOAT;
-def CMP_EQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_EQ>,
-                   CMP_CONDN_DESC_BASE<"eq", Typestr, FGRCCOpnd, FGROpnd,
-                                       setoeq>, ISA_MIPS32R6, HARDFLOAT;
-def CMP_UEQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_UEQ>,
-                    CMP_CONDN_DESC_BASE<"ueq", Typestr, FGRCCOpnd, FGROpnd,
-                                        setueq>, ISA_MIPS32R6, HARDFLOAT;
-def CMP_LT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_LT>,
-                   CMP_CONDN_DESC_BASE<"lt", Typestr, FGRCCOpnd, FGROpnd,
-                                       setolt>, ISA_MIPS32R6, HARDFLOAT;
-def CMP_ULT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_ULT>,
-                    CMP_CONDN_DESC_BASE<"ult", Typestr, FGRCCOpnd, FGROpnd,
-                                        setult>, ISA_MIPS32R6, HARDFLOAT;
-def CMP_LE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_LE>,
-                   CMP_CONDN_DESC_BASE<"le", Typestr, FGRCCOpnd, FGROpnd,
-                                       setole>, ISA_MIPS32R6, HARDFLOAT;
-def CMP_ULE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_ULE>,
-                    CMP_CONDN_DESC_BASE<"ule", Typestr, FGRCCOpnd, FGROpnd,
-                                        setule>, ISA_MIPS32R6, HARDFLOAT;
-def CMP_SAF_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SAF>,
-                    CMP_CONDN_DESC_BASE<"saf", Typestr, FGRCCOpnd, FGROpnd>,
-                    ISA_MIPS32R6, HARDFLOAT;
-def CMP_SUN_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SUN>,
-                    CMP_CONDN_DESC_BASE<"sun", Typestr, FGRCCOpnd, FGROpnd>,
-                    ISA_MIPS32R6, HARDFLOAT;
-def CMP_SEQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SEQ>,
-                    CMP_CONDN_DESC_BASE<"seq", Typestr, FGRCCOpnd, FGROpnd>,
-                    ISA_MIPS32R6, HARDFLOAT;
-def CMP_SUEQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SUEQ>,
-                     CMP_CONDN_DESC_BASE<"sueq", Typestr, FGRCCOpnd, FGROpnd>,
-                     ISA_MIPS32R6, HARDFLOAT;
-def CMP_SLT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SLT>,
-                    CMP_CONDN_DESC_BASE<"slt", Typestr, FGRCCOpnd, FGROpnd>,
-                    ISA_MIPS32R6, HARDFLOAT;
-def CMP_SULT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SULT>,
-                     CMP_CONDN_DESC_BASE<"sult", Typestr, FGRCCOpnd, FGROpnd>,
-                     ISA_MIPS32R6, HARDFLOAT;
-def CMP_SLE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SLE>,
-                    CMP_CONDN_DESC_BASE<"sle", Typestr, FGRCCOpnd, FGROpnd>,
-                    ISA_MIPS32R6, HARDFLOAT;
-def CMP_SULE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SULE>,
-                     CMP_CONDN_DESC_BASE<"sule", Typestr, FGRCCOpnd, FGROpnd>,
-                     ISA_MIPS32R6, HARDFLOAT;
-}
+multiclass CMP_CC_M <FIELD_CMP_FORMAT Format, string Typestr,
+                     RegisterOperand FGROpnd>{
+  let AdditionalPredicates = [NotInMicroMips] in {
+    def CMP_F_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_AF>,
+                      CMP_CONDN_DESC_BASE<"af", Typestr, FGROpnd>,
+                      ISA_MIPS32R6, HARDFLOAT;
+    def CMP_UN_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_UN>,
+                       CMP_CONDN_DESC_BASE<"un", Typestr, FGROpnd, setuo>,
+                       ISA_MIPS32R6, HARDFLOAT;
+    def CMP_EQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_EQ>,
+                       CMP_CONDN_DESC_BASE<"eq", Typestr, FGROpnd, setoeq>,
+                       ISA_MIPS32R6, HARDFLOAT;
+    def CMP_UEQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_UEQ>,
+                        CMP_CONDN_DESC_BASE<"ueq", Typestr, FGROpnd, setueq>,
+                        ISA_MIPS32R6, HARDFLOAT;
+    def CMP_LT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_LT>,
+                       CMP_CONDN_DESC_BASE<"lt", Typestr, FGROpnd, setolt>,
+                       ISA_MIPS32R6, HARDFLOAT;
+    def CMP_ULT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_ULT>,
+                        CMP_CONDN_DESC_BASE<"ult", Typestr, FGROpnd, setult>,
+                        ISA_MIPS32R6, HARDFLOAT;
+    def CMP_LE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_LE>,
+                       CMP_CONDN_DESC_BASE<"le", Typestr, FGROpnd, setole>,
+                       ISA_MIPS32R6, HARDFLOAT;
+    def CMP_ULE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_ULE>,
+                        CMP_CONDN_DESC_BASE<"ule", Typestr, FGROpnd, setule>,
+                        ISA_MIPS32R6, HARDFLOAT;
+    def CMP_SAF_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SAF>,
+                        CMP_CONDN_DESC_BASE<"saf", Typestr, FGROpnd>,
+                        ISA_MIPS32R6, HARDFLOAT;
+    def CMP_SUN_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SUN>,
+                        CMP_CONDN_DESC_BASE<"sun", Typestr, FGROpnd>,
+                        ISA_MIPS32R6, HARDFLOAT;
+    def CMP_SEQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SEQ>,
+                        CMP_CONDN_DESC_BASE<"seq", Typestr, FGROpnd>,
+                        ISA_MIPS32R6, HARDFLOAT;
+    def CMP_SUEQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SUEQ>,
+                         CMP_CONDN_DESC_BASE<"sueq", Typestr, FGROpnd>,
+                         ISA_MIPS32R6, HARDFLOAT;
+    def CMP_SLT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SLT>,
+                        CMP_CONDN_DESC_BASE<"slt", Typestr, FGROpnd>,
+                        ISA_MIPS32R6, HARDFLOAT;
+    def CMP_SULT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SULT>,
+                         CMP_CONDN_DESC_BASE<"sult", Typestr, FGROpnd>,
+                         ISA_MIPS32R6, HARDFLOAT;
+    def CMP_SLE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SLE>,
+                        CMP_CONDN_DESC_BASE<"sle", Typestr, FGROpnd>,
+                        ISA_MIPS32R6, HARDFLOAT;
+    def CMP_SULE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SULE>,
+                         CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd>,
+                         ISA_MIPS32R6, HARDFLOAT;
+  }
 }
 
 //===----------------------------------------------------------------------===//
@@ -472,8 +472,7 @@
 class MUL_R6_DESC : MUL_R6_DESC_BASE<"mul", GPR32Opnd, mul>;
 class MULU_DESC   : MUL_R6_DESC_BASE<"mulu", GPR32Opnd>;
 
-class COP1_SEL_DESC_BASE<string instr_asm, RegisterOperand FGRCCOpnd,
-                         RegisterOperand FGROpnd> {
+class COP1_SEL_DESC_BASE<string instr_asm, RegisterOperand FGROpnd> {
   dag OutOperandList = (outs FGROpnd:$fd);
   dag InOperandList = (ins FGRCCOpnd:$fd_in, FGROpnd:$fs, FGROpnd:$ft);
   string AsmString = !strconcat(instr_asm, "\t$fd, $fs, $ft");
@@ -483,12 +482,11 @@
   string Constraints = "$fd_in = $fd";
 }
 
-class SEL_D_DESC : COP1_SEL_DESC_BASE<"sel.d", FGRCC32Opnd, FGR64Opnd> {
+class SEL_D_DESC : COP1_SEL_DESC_BASE<"sel.d", FGR64Opnd> {
   // We must insert a SUBREG_TO_REG around $fd_in
   bit usesCustomInserter = 1;
 }
-
-class SEL_S_DESC : COP1_SEL_DESC_BASE<"sel.s", FGRCC32Opnd, FGR32Opnd>;
+class SEL_S_DESC : COP1_SEL_DESC_BASE<"sel.s", FGR32Opnd>;
 
 class SELEQNE_Z_DESC_BASE<string instr_asm, RegisterOperand GPROpnd>
     : MipsR6Arch<instr_asm> {
@@ -695,8 +693,8 @@
 }
 def CLO_R6 : R6MMR6Rel, CLO_R6_ENC, CLO_R6_DESC, ISA_MIPS32R6;
 def CLZ_R6 : R6MMR6Rel, CLZ_R6_ENC, CLZ_R6_DESC, ISA_MIPS32R6;
-defm S : CMP_CC_M<FIELD_CMP_FORMAT_S, "s", FGRCC32Opnd, FGR32Opnd>;
-defm D : CMP_CC_M<FIELD_CMP_FORMAT_D, "d", FGRCC32Opnd, FGR64Opnd>;
+defm S : CMP_CC_M<FIELD_CMP_FORMAT_S, "s", FGR32Opnd>;
+defm D : CMP_CC_M<FIELD_CMP_FORMAT_D, "d", FGR64Opnd>;
 def DIV : R6MMR6Rel, DIV_ENC, DIV_DESC, ISA_MIPS32R6;
 def DIVU : R6MMR6Rel, DIVU_ENC, DIVU_DESC, ISA_MIPS32R6;
 def JIALC : R6MMR6Rel, JIALC_ENC, JIALC_DESC, ISA_MIPS32R6;
diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td
index 0001a1b..69c126a 100644
--- a/llvm/lib/Target/Mips/Mips64InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td
@@ -98,14 +98,10 @@
               ADDI_FM<0x19>, IsAsCheapAsAMove, ISA_MIPS3;
 
 let isCodeGenOnly = 1 in {
-def SLTi64 : SetCC_I<"slti", setlt, simm16_64, immSExt16, GPR64Opnd,
-                     GPR64Opnd>, SLTI_FM<0xa>;
-def SLTiu64 : SetCC_I<"sltiu", setult, simm16_64, immSExt16, GPR64Opnd,
-                      GPR64Opnd>, SLTI_FM<0xb>;
-def SLTi64_32 : SetCC_I<"slti", setlt, simm16, immSExt16, GPR64Opnd,
-                        GPR32Opnd>, SLTI_FM<0xa>;
-def SLTiu64_32 : SetCC_I<"sltiu", setult, simm16, immSExt16, GPR64Opnd,
-                         GPR32Opnd>, SLTI_FM<0xb>;
+def SLTi64  : SetCC_I<"slti", setlt, simm16_64, immSExt16, GPR64Opnd>,
+              SLTI_FM<0xa>;
+def SLTiu64 : SetCC_I<"sltiu", setult, simm16_64, immSExt16, GPR64Opnd>,
+              SLTI_FM<0xb>;
 def ANDi64 : ArithLogicI<"andi", uimm16_64, GPR64Opnd, II_AND, immZExt16, and>,
              ADDI_FM<0xc>;
 def ORi64   : ArithLogicI<"ori", uimm16_64, GPR64Opnd, II_OR, immZExt16, or>,
@@ -126,10 +122,8 @@
              ISA_MIPS3;
 
 let isCodeGenOnly = 1 in {
-def SLT64 : SetCC_R<"slt", setlt, GPR64Opnd, GPR64Opnd>, ADD_FM<0, 0x2a>;
-def SLTu64 : SetCC_R<"sltu", setult, GPR64Opnd, GPR64Opnd>, ADD_FM<0, 0x2b>;
-def SLT64_32 : SetCC_R<"slt", setlt, GPR64Opnd, GPR32Opnd>, ADD_FM<0, 0x2a>;
-def SLTu64_32 : SetCC_R<"sltu", setult, GPR64Opnd, GPR32Opnd>, ADD_FM<0, 0x2b>;
+def SLT64  : SetCC_R<"slt", setlt, GPR64Opnd>, ADD_FM<0, 0x2a>;
+def SLTu64 : SetCC_R<"sltu", setult, GPR64Opnd>, ADD_FM<0, 0x2b>;
 def AND64  : ArithLogicR<"and", GPR64Opnd, 1, II_AND, and>, ADD_FM<0, 0x24>;
 def OR64   : ArithLogicR<"or", GPR64Opnd, 1, II_OR, or>, ADD_FM<0, 0x25>;
 def XOR64  : ArithLogicR<"xor", GPR64Opnd, 1, II_XOR, xor>, ADD_FM<0, 0x26>;
@@ -331,7 +325,8 @@
 class SetCC64_R<string opstr, PatFrag cond_op> :
   InstSE<(outs GPR64Opnd:$rd), (ins GPR64Opnd:$rs, GPR64Opnd:$rt),
          !strconcat(opstr, "\t$rd, $rs, $rt"),
-         [(set GPR64Opnd:$rd, (cond_op GPR64Opnd:$rs, GPR64Opnd:$rt))],
+         [(set GPR64Opnd:$rd, (zext (cond_op GPR64Opnd:$rs,
+                                             GPR64Opnd:$rt)))],
          II_SEQ_SNE, FrmR, opstr> {
   let TwoOperandAliasConstraint = "$rd = $rs";
 }
@@ -339,7 +334,8 @@
 class SetCC64_I<string opstr, PatFrag cond_op>:
   InstSE<(outs GPR64Opnd:$rt), (ins GPR64Opnd:$rs, simm10_64:$imm10),
          !strconcat(opstr, "\t$rt, $rs, $imm10"),
-         [(set GPR64Opnd:$rt, (cond_op GPR64Opnd:$rs, immSExt10_64:$imm10))],
+         [(set GPR64Opnd:$rt, (zext (cond_op GPR64Opnd:$rs,
+                                             immSExt10_64:$imm10)))],
          II_SEQI_SNEI, FrmI, opstr> {
   let TwoOperandAliasConstraint = "$rt = $rs";
 }
@@ -348,7 +344,7 @@
                     RegisterOperand RO, Operand ImmOp, bits<64> shift = 1> :
   InstSE<(outs), (ins RO:$rs, ImmOp:$p, opnd:$offset),
          !strconcat(opstr, "\t$rs, $p, $offset"),
-         [(brcond (i64 (cond_op (and RO:$rs, (shl shift, immZExt5_64:$p)), 0)),
+         [(brcond (i32 (cond_op (and RO:$rs, (shl shift, immZExt5_64:$p)), 0)),
                   bb:$offset)], II_BBIT, FrmI, opstr> {
   let isBranch = 1;
   let isTerminator = 1;
@@ -484,30 +480,20 @@
 def : WrapperPat<tjumptable, DADDiu, GPR64>;
 def : WrapperPat<tglobaltlsaddr, DADDiu, GPR64>;
 
-defm : BrcondPats1<GPR64, BEQ64, BNE64, ZERO_64, i64>;
-defm : BrcondPats1<GPR32, BEQ, BNE, ZERO, i64>;
+defm : BrcondPats<GPR64, BEQ64, BNE64, SLT64, SLTu64, SLTi64, SLTiu64,
+                  ZERO_64>;
 
-def : MipsPat<(brcond (i64 (setlt i64:$lhs, 1)), bb:$dst),
+def : MipsPat<(brcond (i32 (setlt i64:$lhs, 1)), bb:$dst),
               (BLEZ64 i64:$lhs, bb:$dst)>;
-def : MipsPat<(brcond (i64 (setgt i64:$lhs, -1)), bb:$dst),
+def : MipsPat<(brcond (i32 (setgt i64:$lhs, -1)), bb:$dst),
               (BGEZ64 i64:$lhs, bb:$dst)>;
-def : MipsPat<(brcond (i64 (setlt i32:$lhs, 1)), bb:$dst),
-              (BLEZ64 (SUBREG_TO_REG (i32 0), i32:$lhs, sub_32), bb:$dst)>;
-def : MipsPat<(brcond (i64 (setgt i32:$lhs, -1)), bb:$dst),
-              (BGEZ64 (SUBREG_TO_REG (i32 0), i32:$lhs, sub_32), bb:$dst)>;
 
 // setcc patterns
 defm : SeteqPats<GPR64, SLTiu64, XOR64, SLTu64, ZERO_64>;
-defm : SetlePats<GPR64, SLT64, SLTu64, XORi64>;
+defm : SetlePats<GPR64, SLT64, SLTu64>;
 defm : SetgtPats<GPR64, SLT64, SLTu64>;
-defm : SetgePats<GPR64, SLT64, SLTu64, XORi64>;
-defm : SetgeImmPats<GPR64, SLTi64, SLTiu64, XORi64>;
-
-defm : SeteqPats<GPR32, SLTiu64_32, XOR, SLTu64_32, ZERO>;
-defm : SetlePats<GPR32, SLT64_32, SLTu64_32, XORi64>;
-defm : SetgtPats<GPR32, SLT64_32, SLTu64_32>;
-defm : SetgePats<GPR32, SLT64_32, SLTu64_32, XORi64>;
-defm : SetgeImmPats<GPR32, SLTi64_32, SLTiu64_32, XORi64>;
+defm : SetgePats<GPR64, SLT64, SLTu64>;
+defm : SetgeImmPats<GPR64, SLTi64, SLTiu64>;
 
 // truncate
 def : MipsPat<(trunc (assertsext GPR64:$src)),
@@ -552,13 +538,13 @@
 
 // Octeon bbit0/bbit1 MipsPattern
 let Predicates = [HasMips64, HasCnMips] in {
-def : MipsPat<(brcond (i64 (seteq (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst),
+def : MipsPat<(brcond (i32 (seteq (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst),
               (BBIT0 i64:$lhs, (Log2LO PowerOf2LO:$mask), bb:$dst)>;
-def : MipsPat<(brcond (i64 (seteq (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst),
+def : MipsPat<(brcond (i32 (seteq (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst),
               (BBIT032 i64:$lhs, (Log2HI PowerOf2HI:$mask), bb:$dst)>;
-def : MipsPat<(brcond (i64 (setne (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst),
+def : MipsPat<(brcond (i32 (setne (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst),
               (BBIT1 i64:$lhs, (Log2LO PowerOf2LO:$mask), bb:$dst)>;
-def : MipsPat<(brcond (i64 (setne (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst),
+def : MipsPat<(brcond (i32 (setne (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst),
               (BBIT132 i64:$lhs, (Log2HI PowerOf2HI:$mask), bb:$dst)>;
 }
 
diff --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
index 6f940b7..6f34dbe 100644
--- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
@@ -74,11 +74,6 @@
 class SCD_R6_DESC   : SC_R6_DESC_BASE<"scd", GPR64Opnd>;
 class SELEQZ64_DESC : SELEQNE_Z_DESC_BASE<"seleqz", GPR64Opnd>;
 class SELNEZ64_DESC : SELEQNE_Z_DESC_BASE<"selnez", GPR64Opnd>;
-class SEL64_S_DESC : COP1_SEL_DESC_BASE<"sel.s", FGRCC64Opnd, FGR32Opnd> {
-  // We must copy FGRCC64Opnd's subreg into FGR32.
-  bit usesCustomInserter = 1;
-}
-class SEL64_D_DESC : COP1_SEL_DESC_BASE<"sel.d", FGRCC64Opnd, FGR64Opnd>;
 
 //===----------------------------------------------------------------------===//
 //
@@ -105,18 +100,11 @@
 def DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6;
 def DMULU: DMULU_ENC, DMULU_DESC, ISA_MIPS64R6;
 def LDPC: LDPC_ENC, LDPC_DESC, ISA_MIPS64R6;
-def LLD_R6 : LLD_R6_ENC, LLD_R6_DESC, ISA_MIPS64R6;
-def SCD_R6 : SCD_R6_ENC, SCD_R6_DESC, ISA_MIPS64R6;
-let AdditionalPredicates = [NotInMicroMips],
-    DecoderNamespace = "Mips64r6" in {
-  def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS64R6;
-  def SELNEZ64 : SELNEZ_ENC, SELNEZ64_DESC, ISA_MIPS64R6;
-  def SEL64_S : SEL_S_ENC, SEL64_S_DESC, ISA_MIPS64R6, HARDFLOAT;
-  def SEL64_D : SEL_D_ENC, SEL64_D_DESC, ISA_MIPS64R6, HARDFLOAT;
-  defm S64: CMP_CC_M<FIELD_CMP_FORMAT_S, "s", FGRCC64Opnd, FGR32Opnd>,
-            ISA_MIPS64R6;
-  defm D64: CMP_CC_M<FIELD_CMP_FORMAT_D, "d", FGRCC64Opnd, FGR64Opnd>,
-            ISA_MIPS64R6;
+def LLD_R6 : LLD_R6_ENC, LLD_R6_DESC, ISA_MIPS32R6;
+def SCD_R6 : SCD_R6_ENC, SCD_R6_DESC, ISA_MIPS32R6;
+let DecoderNamespace = "Mips32r6_64r6_GP64" in {
+  def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS32R6, GPR_64;
+  def SELNEZ64 : SELNEZ_ENC, SELNEZ64_DESC, ISA_MIPS32R6, GPR_64;
 }
 
 //===----------------------------------------------------------------------===//
@@ -133,71 +121,99 @@
 //
 //===----------------------------------------------------------------------===//
 
-// comparisons supported via another comparison
-defm S64: Cmp_Pats<f32, NOR64, ZERO_64>, ISA_MIPS64R6;
-defm D64: Cmp_Pats<f64, NOR64, ZERO_64>, ISA_MIPS64R6;
-
-// i32 selects
-defm : SelectInt_Pats<i32, OR, XORi, SLTi, SLTiu, SELEQZ, SELNEZ,
-                      immZExt16, i64>, ISA_MIPS64R6;
-
-def : MipsPat<(select i64:$cond, i32:$t, i32:$f),
-              (OR (SELNEZ i32:$t, (EXTRACT_SUBREG i64:$cond, sub_32)),
-                  (SELEQZ i32:$f, (EXTRACT_SUBREG i64:$cond, sub_32)))>,
-      ISA_MIPS64R6;
-def : MipsPat<(select i64:$cond, i32:$t, immz),
-              (SELNEZ i32:$t, (EXTRACT_SUBREG i64:$cond, sub_32))>,
-      ISA_MIPS64R6;
-def : MipsPat<(select i64:$cond, immz, i32:$f),
-              (SELEQZ i32:$f, (EXTRACT_SUBREG i64:$cond, sub_32))>,
-      ISA_MIPS64R6;
-
 // i64 selects
-defm : SelectInt_Pats<i64, OR64, XORi64, SLTi64, SLTiu64, SELEQZ64, SELNEZ64,
-                      immZExt16_64, i64>, ISA_MIPS64R6;
-
 def : MipsPat<(select i64:$cond, i64:$t, i64:$f),
               (OR64 (SELNEZ64 i64:$t, i64:$cond),
                     (SELEQZ64 i64:$f, i64:$cond))>,
-      ISA_MIPS64R6;
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (seteq i64:$cond, immz)), i64:$t, i64:$f),
+              (OR64 (SELEQZ64 i64:$t, i64:$cond),
+                    (SELNEZ64 i64:$f, i64:$cond))>,
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (setne i64:$cond, immz)), i64:$t, i64:$f),
+              (OR64 (SELNEZ64 i64:$t, i64:$cond),
+                    (SELEQZ64 i64:$f, i64:$cond))>,
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (seteq i64:$cond, immZExt16_64:$imm)), i64:$t, i64:$f),
+              (OR64 (SELEQZ64 i64:$t, (XORi64 i64:$cond, immZExt16_64:$imm)),
+                    (SELNEZ64 i64:$f, (XORi64 i64:$cond, immZExt16_64:$imm)))>,
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (setne i64:$cond, immZExt16_64:$imm)), i64:$t, i64:$f),
+              (OR64 (SELNEZ64 i64:$t, (XORi64 i64:$cond, immZExt16_64:$imm)),
+                    (SELEQZ64 i64:$f, (XORi64 i64:$cond, immZExt16_64:$imm)))>,
+              ISA_MIPS64R6;
+def : MipsPat<
+  (select (i32 (setgt i64:$cond, immSExt16Plus1:$imm)), i64:$t, i64:$f),
+  (OR64 (SELEQZ64 i64:$t,
+                  (SUBREG_TO_REG (i64 0), (SLTi64 i64:$cond, (Plus1 imm:$imm)),
+                                 sub_32)),
+        (SELNEZ64 i64:$f,
+                  (SUBREG_TO_REG (i64 0), (SLTi64 i64:$cond, (Plus1 imm:$imm)),
+                                 sub_32)))>,
+  ISA_MIPS64R6;
+def : MipsPat<
+  (select (i32 (setugt i64:$cond, immSExt16Plus1:$imm)), i64:$t, i64:$f),
+  (OR64 (SELEQZ64 i64:$t,
+                  (SUBREG_TO_REG (i64 0), (SLTiu64 i64:$cond, (Plus1 imm:$imm)),
+                                 sub_32)),
+        (SELNEZ64 i64:$f,
+                  (SUBREG_TO_REG (i64 0), (SLTiu64 i64:$cond, (Plus1 imm:$imm)),
+                                 sub_32)))>,
+  ISA_MIPS64R6;
+
+def : MipsPat<(select (i32 (setne i64:$cond, immz)), i64:$t, immz),
+              (SELNEZ64 i64:$t, i64:$cond)>, ISA_MIPS64R6;
+def : MipsPat<(select (i32 (seteq i64:$cond, immz)), i64:$t, immz),
+              (SELEQZ64 i64:$t, i64:$cond)>, ISA_MIPS64R6;
+def : MipsPat<(select (i32 (setne i64:$cond, immz)), immz, i64:$f),
+              (SELEQZ64 i64:$f, i64:$cond)>, ISA_MIPS64R6;
+def : MipsPat<(select (i32 (seteq i64:$cond, immz)), immz, i64:$f),
+              (SELNEZ64 i64:$f, i64:$cond)>, ISA_MIPS64R6;
 
 // i64 selects from an i32 comparison
+// One complicating factor here is that bits 32-63 of an i32 are undefined.
+// FIXME: Ideally, setcc would always produce an i64 on MIPS64 targets.
+//        This would allow us to remove the sign-extensions here.
 def : MipsPat<(select i32:$cond, i64:$t, i64:$f),
-      (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)),
-            (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>,
-      ISA_MIPS64R6;
-def : MipsPat<(select (i64 (seteq i32:$cond, immz)), i64:$t, i64:$f),
-      (OR64 (SELEQZ64 i64:$t, (SLL64_32 i32:$cond)),
-            (SELNEZ64 i64:$f, (SLL64_32 i32:$cond)))>,
-      ISA_MIPS64R6;
-def : MipsPat<(select (i64 (setne i32:$cond, immz)), i64:$t, i64:$f),
-      (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)),
-            (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>,
-      ISA_MIPS64R6;
-def : MipsPat<(select (i64 (seteq i32:$cond, immZExt16:$imm)), i64:$t, i64:$f),
-      (OR64 (SELEQZ64 i64:$t, (SLL64_32 (XORi i32:$cond, immZExt16:$imm))),
-            (SELNEZ64 i64:$f, (SLL64_32 (XORi i32:$cond, immZExt16:$imm))))>,
-      ISA_MIPS64R6;
-def : MipsPat<(select (i64 (setne i32:$cond, immZExt16:$imm)), i64:$t, i64:$f),
-      (OR64 (SELNEZ64 i64:$t, (SLL64_32 (XORi i32:$cond, immZExt16:$imm))),
-            (SELEQZ64 i64:$f, (SLL64_32 (XORi i32:$cond, immZExt16:$imm))))>,
-      ISA_MIPS64R6;
+              (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)),
+                    (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>,
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (seteq i32:$cond, immz)), i64:$t, i64:$f),
+              (OR64 (SELEQZ64 i64:$t, (SLL64_32 i32:$cond)),
+                    (SELNEZ64 i64:$f, (SLL64_32 i32:$cond)))>,
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (setne i32:$cond, immz)), i64:$t, i64:$f),
+              (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)),
+                    (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>,
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (seteq i32:$cond, immZExt16:$imm)), i64:$t, i64:$f),
+              (OR64 (SELEQZ64 i64:$t, (SLL64_32 (XORi i32:$cond,
+                                                      immZExt16:$imm))),
+                    (SELNEZ64 i64:$f, (SLL64_32 (XORi i32:$cond,
+                                                      immZExt16:$imm))))>,
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (setne i32:$cond, immZExt16:$imm)), i64:$t, i64:$f),
+              (OR64 (SELNEZ64 i64:$t, (SLL64_32 (XORi i32:$cond,
+                                                      immZExt16:$imm))),
+                    (SELEQZ64 i64:$f, (SLL64_32 (XORi i32:$cond,
+                                                      immZExt16:$imm))))>,
+              ISA_MIPS64R6;
 
 def : MipsPat<(select i32:$cond, i64:$t, immz),
               (SELNEZ64 i64:$t, (SLL64_32 i32:$cond))>,
-      ISA_MIPS64R6;
-def : MipsPat<(select (i64 (setne i32:$cond, immz)), i64:$t, immz),
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (setne i32:$cond, immz)), i64:$t, immz),
               (SELNEZ64 i64:$t, (SLL64_32 i32:$cond))>,
-      ISA_MIPS64R6;
-def : MipsPat<(select (i64 (seteq i32:$cond, immz)), i64:$t, immz),
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (seteq i32:$cond, immz)), i64:$t, immz),
               (SELEQZ64 i64:$t, (SLL64_32 i32:$cond))>,
-      ISA_MIPS64R6;
+              ISA_MIPS64R6;
 def : MipsPat<(select i32:$cond, immz, i64:$f),
               (SELEQZ64 i64:$f, (SLL64_32 i32:$cond))>,
-      ISA_MIPS64R6;
-def : MipsPat<(select (i64 (setne i32:$cond, immz)), immz, i64:$f),
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (setne i32:$cond, immz)), immz, i64:$f),
               (SELEQZ64 i64:$f, (SLL64_32 i32:$cond))>,
-      ISA_MIPS64R6;
-def : MipsPat<(select (i64 (seteq i32:$cond, immz)), immz, i64:$f),
+              ISA_MIPS64R6;
+def : MipsPat<(select (i32 (seteq i32:$cond, immz)), immz, i64:$f),
               (SELNEZ64 i64:$f, (SLL64_32 i32:$cond))>,
-      ISA_MIPS64R6;
+              ISA_MIPS64R6;
diff --git a/llvm/lib/Target/Mips/MipsCondMov.td b/llvm/lib/Target/Mips/MipsCondMov.td
index b593ffe..2d96d9b 100644
--- a/llvm/lib/Target/Mips/MipsCondMov.td
+++ b/llvm/lib/Target/Mips/MipsCondMov.td
@@ -52,6 +52,57 @@
   let Constraints = "$F = $fd";
 }
 
+// select patterns
+multiclass MovzPats0<RegisterClass CRC, RegisterClass DRC,
+                     Instruction MOVZInst, Instruction SLTOp,
+                     Instruction SLTuOp, Instruction SLTiOp,
+                     Instruction SLTiuOp> {
+  def : MipsPat<(select (i32 (setge CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
+                (MOVZInst DRC:$T, (SLTOp CRC:$lhs, CRC:$rhs), DRC:$F)>;
+  def : MipsPat<(select (i32 (setuge CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
+                (MOVZInst DRC:$T, (SLTuOp CRC:$lhs, CRC:$rhs), DRC:$F)>;
+  def : MipsPat<(select (i32 (setge CRC:$lhs, immSExt16:$rhs)), DRC:$T, DRC:$F),
+                (MOVZInst DRC:$T, (SLTiOp CRC:$lhs, immSExt16:$rhs), DRC:$F)>;
+  def : MipsPat<(select (i32 (setuge CRC:$lh, immSExt16:$rh)), DRC:$T, DRC:$F),
+                (MOVZInst DRC:$T, (SLTiuOp CRC:$lh, immSExt16:$rh), DRC:$F)>;
+  def : MipsPat<(select (i32 (setle CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
+                (MOVZInst DRC:$T, (SLTOp CRC:$rhs, CRC:$lhs), DRC:$F)>;
+  def : MipsPat<(select (i32 (setule CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
+                (MOVZInst DRC:$T, (SLTuOp CRC:$rhs, CRC:$lhs), DRC:$F)>;
+  def : MipsPat<(select (i32 (setgt CRC:$lhs, immSExt16Plus1:$rhs)),
+                        DRC:$T, DRC:$F),
+                (MOVZInst DRC:$T, (SLTiOp CRC:$lhs, (Plus1 imm:$rhs)), DRC:$F)>;
+  def : MipsPat<(select (i32 (setugt CRC:$lhs, immSExt16Plus1:$rhs)),
+                        DRC:$T, DRC:$F),
+                (MOVZInst DRC:$T, (SLTiuOp CRC:$lhs, (Plus1 imm:$rhs)),
+                          DRC:$F)>;
+}
+
+multiclass MovzPats1<RegisterClass CRC, RegisterClass DRC,
+                     Instruction MOVZInst, Instruction XOROp> {
+  def : MipsPat<(select (i32 (seteq CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
+                (MOVZInst DRC:$T, (XOROp CRC:$lhs, CRC:$rhs), DRC:$F)>;
+  def : MipsPat<(select (i32 (seteq CRC:$lhs, 0)), DRC:$T, DRC:$F),
+                (MOVZInst DRC:$T, CRC:$lhs, DRC:$F)>;
+}
+
+multiclass MovzPats2<RegisterClass CRC, RegisterClass DRC,
+                     Instruction MOVZInst, Instruction XORiOp> {
+  def : MipsPat<
+            (select (i32 (seteq CRC:$lhs, immZExt16:$uimm16)), DRC:$T, DRC:$F),
+            (MOVZInst DRC:$T, (XORiOp CRC:$lhs, immZExt16:$uimm16), DRC:$F)>;
+}
+
+multiclass MovnPats<RegisterClass CRC, RegisterClass DRC, Instruction MOVNInst,
+                    Instruction XOROp> {
+  def : MipsPat<(select (i32 (setne CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
+                (MOVNInst DRC:$T, (XOROp CRC:$lhs, CRC:$rhs), DRC:$F)>;
+  def : MipsPat<(select CRC:$cond, DRC:$T, DRC:$F),
+                (MOVNInst DRC:$T, CRC:$cond, DRC:$F)>;
+  def : MipsPat<(select (i32 (setne CRC:$lhs, 0)),DRC:$T, DRC:$F),
+                (MOVNInst DRC:$T, CRC:$lhs, DRC:$F)>;
+}
+
 // Instantiation of instructions.
 def MOVZ_I_I : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd, II_MOVZ>,
                ADD_FM<0, 0xa>, INSN_MIPS4_32_NOT_32R6_64R6;
@@ -148,189 +199,96 @@
                  CMov_F_F_FM<17, 0>, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
 }
 
-// select patterns
-multiclass MovzPats0<RegisterClass CRC, RegisterClass DRC,
-                     Instruction MOVZInst, Instruction SLTOp,
-                     Instruction SLTuOp, Instruction SLTiOp,
-                     Instruction SLTiuOp, ValueType VT> {
-// reg, reg
-def : MipsPat<(select (VT (setge CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
-              (MOVZInst DRC:$T, (SLTOp CRC:$lhs, CRC:$rhs), DRC:$F)>;
-def : MipsPat<(select (VT (setuge CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
-              (MOVZInst DRC:$T, (SLTuOp CRC:$lhs, CRC:$rhs), DRC:$F)>;
-def : MipsPat<(select (VT (setle CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
-              (MOVZInst DRC:$T, (SLTOp CRC:$rhs, CRC:$lhs), DRC:$F)>;
-def : MipsPat<(select (VT (setule CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
-              (MOVZInst DRC:$T, (SLTuOp CRC:$rhs, CRC:$lhs), DRC:$F)>;
-
-// reg, imm
-def : MipsPat<(select (VT (setge CRC:$lhs, immSExt16:$rhs)), DRC:$T, DRC:$F),
-              (MOVZInst DRC:$T, (SLTiOp CRC:$lhs, immSExt16:$rhs), DRC:$F)>;
-def : MipsPat<(select (VT (setuge CRC:$lh, immSExt16:$rh)), DRC:$T, DRC:$F),
-              (MOVZInst DRC:$T, (SLTiuOp CRC:$lh, immSExt16:$rh), DRC:$F)>;
-def : MipsPat<
-        (select (VT (setgt CRC:$lhs, immSExt16Plus1:$rhs)), DRC:$T, DRC:$F),
-        (MOVZInst DRC:$T, (SLTiOp CRC:$lhs, (Plus1 imm:$rhs)), DRC:$F)>;
-def : MipsPat<
-        (select (VT (setugt CRC:$lhs, immSExt16Plus1:$rhs)), DRC:$T, DRC:$F),
-        (MOVZInst DRC:$T, (SLTiuOp CRC:$lhs, (Plus1 imm:$rhs)), DRC:$F)>;
-}
-
-// We have to wrap the instantiation of the MovzPats0 patterns in another
-// multiclass that specifies the result type of the SETCC nodes. The patterns
-// with VT=i64 (or i32) will be ignored when GPR-width=i32 (or i64).
-multiclass MovzPats0_SuperClass<ValueType VT> {
-defm : MovzPats0<GPR32, GPR32, MOVZ_I_I, SLT, SLTu, SLTi, SLTiu, VT>,
+// Instantiation of conditional move patterns.
+defm : MovzPats0<GPR32, GPR32, MOVZ_I_I, SLT, SLTu, SLTi, SLTiu>,
        INSN_MIPS4_32_NOT_32R6_64R6;
-defm : MovzPats0<GPR32, GPR64, MOVZ_I_I64, SLT, SLTu, SLTi, SLTiu, VT>,
-       INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats0<GPR32, FGR32, MOVZ_I_S, SLT, SLTu, SLTi, SLTiu, VT>,
-       INSN_MIPS4_32_NOT_32R6_64R6;
-defm : MovzPats0<GPR32, AFGR64, MOVZ_I_D32, SLT, SLTu, SLTi, SLTiu, VT>,
-       INSN_MIPS4_32_NOT_32R6_64R6, FGR_32;
-defm : MovzPats0<GPR32, FGR64, MOVZ_I_D64, SLT, SLTu, SLTi, SLTiu, VT>,
-       INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
+defm : MovzPats1<GPR32, GPR32, MOVZ_I_I, XOR>, INSN_MIPS4_32_NOT_32R6_64R6;
+defm : MovzPats2<GPR32, GPR32, MOVZ_I_I, XORi>, INSN_MIPS4_32_NOT_32R6_64R6;
 
-defm : MovzPats0<GPR32, GPR32, MOVZ_I64_I, SLT64_32, SLTu64_32, SLTi64_32,
-                 SLTiu64_32, VT>, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats0<GPR32, GPR64, MOVZ_I64_I64, SLT64_32, SLTu64_32, SLTi64_32,
-                 SLTiu64_32, VT>, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats0<GPR32, FGR32, MOVZ_I64_S, SLT64_32, SLTu64_32, SLTi64_32,
-                 SLTiu64_32, VT>, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats0<GPR32, FGR64, MOVZ_I64_D64, SLT64_32, SLTu64_32, SLTi64_32,
-                 SLTiu64_32, VT>, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64, FGR_64;
-
-defm : MovzPats0<GPR64, GPR32, MOVZ_I64_I, SLT64, SLTu64, SLTi64, SLTiu64, VT>,
+defm : MovzPats0<GPR32, GPR64, MOVZ_I_I64, SLT, SLTu, SLTi, SLTiu>,
        INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats0<GPR64, GPR64, MOVZ_I64_I64, SLT64, SLTu64, SLTi64, SLTiu64, VT>,
+defm : MovzPats0<GPR64, GPR32, MOVZ_I_I, SLT64, SLTu64, SLTi64, SLTiu64>,
        INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats0<GPR64, FGR32, MOVZ_I64_S, SLT64, SLTu64, SLTi64, SLTiu64, VT>,
+defm : MovzPats0<GPR64, GPR64, MOVZ_I_I64, SLT64, SLTu64, SLTi64, SLTiu64>,
        INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats0<GPR64, FGR64, MOVZ_I64_D64, SLT64, SLTu64, SLTi64, SLTiu64, VT>,
-       INSN_MIPS4_32_NOT_32R6_64R6, GPR_64, FGR_64;
-}
-
-defm : MovzPats0_SuperClass<i32>;
-defm : MovzPats0_SuperClass<i64>;
-
-multiclass MovzPats1<RegisterClass CRC, RegisterClass DRC,
-                     Instruction MOVZInst, Instruction XOROp, ValueType VT> {
-def : MipsPat<(select (VT (seteq CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
-              (MOVZInst DRC:$T, (XOROp CRC:$lhs, CRC:$rhs), DRC:$F)>;
-def : MipsPat<(select (VT (seteq CRC:$lhs, 0)), DRC:$T, DRC:$F),
-              (MOVZInst DRC:$T, CRC:$lhs, DRC:$F)>;
-}
-
-multiclass MovzPats1_SuperClass<ValueType VT> {
-defm : MovzPats1<GPR32, GPR32, MOVZ_I_I, XOR, VT>, INSN_MIPS4_32_NOT_32R6_64R6;
-defm : MovzPats1<GPR32, GPR64, MOVZ_I_I64, XOR, VT>,
+defm : MovzPats1<GPR32, GPR64, MOVZ_I_I64, XOR>,
        INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats1<GPR32, FGR32, MOVZ_I_S, XOR, VT>, INSN_MIPS4_32_NOT_32R6_64R6;
-defm : MovzPats1<GPR32, AFGR64, MOVZ_I_D32, XOR, VT>,
-       INSN_MIPS4_32_NOT_32R6_64R6, FGR_32;
-defm : MovzPats1<GPR32, FGR64, MOVZ_I_D64, XOR, VT>,
-       INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
-
-defm : MovzPats1<GPR64, GPR32, MOVZ_I64_I, XOR64, VT>,
+defm : MovzPats1<GPR64, GPR32, MOVZ_I64_I, XOR64>,
        INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats1<GPR64, GPR64, MOVZ_I64_I64, XOR64, VT>,
+defm : MovzPats1<GPR64, GPR64, MOVZ_I64_I64, XOR64>,
        INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats1<GPR64, FGR32, MOVZ_I64_S, XOR64, VT>,
+defm : MovzPats2<GPR32, GPR64, MOVZ_I_I64, XORi>,
        INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats1<GPR64, FGR64, MOVZ_I64_D64, XOR64, VT>,
-       INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
-}
-
-defm : MovzPats1_SuperClass<i32>;
-defm : MovzPats1_SuperClass<i64>;
-
-multiclass MovzPats2<RegisterClass CRC, RegisterClass DRC,
-                     Instruction MOVZInst, Instruction XORiOp, ValueType VT> {
-def : MipsPat<
-    (select (VT (seteq CRC:$lhs, immZExt16:$uimm16)), DRC:$T, DRC:$F),
-    (MOVZInst DRC:$T, (XORiOp CRC:$lhs, immZExt16:$uimm16), DRC:$F)>;
-}
-
-multiclass MovzPats2_SuperClass<ValueType VT> {
-defm : MovzPats2<GPR32, GPR32, MOVZ_I_I, XORi, VT>, INSN_MIPS4_32_NOT_32R6_64R6;
-defm : MovzPats2<GPR32, GPR64, MOVZ_I_I64, XORi, VT>,
+defm : MovzPats2<GPR64, GPR32, MOVZ_I64_I, XORi64>,
        INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats2<GPR64, GPR32, MOVZ_I64_I, XORi64, VT>,
+defm : MovzPats2<GPR64, GPR64, MOVZ_I64_I64, XORi64>,
        INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovzPats2<GPR64, GPR64, MOVZ_I64_I64, XORi64, VT>,
-       INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-}
-
-defm : MovzPats2_SuperClass<i32>;
-defm : MovzPats2_SuperClass<i64>;
-
-multiclass MovnPats<RegisterClass CRC, RegisterClass DRC, Instruction MOVNInst,
-                    Instruction XOROp, ValueType VT = i32> {
-  def : MipsPat<(select (VT (setne CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F),
-                (MOVNInst DRC:$T, (XOROp CRC:$lhs, CRC:$rhs), DRC:$F)>;
-  def : MipsPat<(select CRC:$cond, DRC:$T, DRC:$F),
-                (MOVNInst DRC:$T, CRC:$cond, DRC:$F)>;
-  def : MipsPat<(select (VT (setne CRC:$lhs, 0)),DRC:$T, DRC:$F),
-                (MOVNInst DRC:$T, CRC:$lhs, DRC:$F)>;
-}
 
 defm : MovnPats<GPR32, GPR32, MOVN_I_I, XOR>, INSN_MIPS4_32_NOT_32R6_64R6;
+
+defm : MovnPats<GPR32, GPR64, MOVN_I_I64, XOR>, INSN_MIPS4_32_NOT_32R6_64R6,
+       GPR_64;
+defm : MovnPats<GPR64, GPR32, MOVN_I64_I, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
+       GPR_64;
+defm : MovnPats<GPR64, GPR64, MOVN_I64_I64, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
+       GPR_64;
+
+defm : MovzPats0<GPR32, FGR32, MOVZ_I_S, SLT, SLTu, SLTi, SLTiu>,
+       INSN_MIPS4_32_NOT_32R6_64R6;
+defm : MovzPats1<GPR32, FGR32, MOVZ_I_S, XOR>, INSN_MIPS4_32_NOT_32R6_64R6;
 defm : MovnPats<GPR32, FGR32, MOVN_I_S, XOR>, INSN_MIPS4_32_NOT_32R6_64R6;
+
+defm : MovzPats0<GPR64, FGR32, MOVZ_I_S, SLT64, SLTu64, SLTi64, SLTiu64>,
+       INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
+defm : MovzPats1<GPR64, FGR32, MOVZ_I64_S, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
+       GPR_64;
+defm : MovnPats<GPR64, FGR32, MOVN_I64_S, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
+       GPR_64;
+
+defm : MovzPats0<GPR32, AFGR64, MOVZ_I_D32, SLT, SLTu, SLTi, SLTiu>,
+       INSN_MIPS4_32_NOT_32R6_64R6, FGR_32;
+defm : MovzPats1<GPR32, AFGR64, MOVZ_I_D32, XOR>, INSN_MIPS4_32_NOT_32R6_64R6,
+       FGR_32;
 defm : MovnPats<GPR32, AFGR64, MOVN_I_D32, XOR>, INSN_MIPS4_32_NOT_32R6_64R6,
        FGR_32;
+
+defm : MovzPats0<GPR32, FGR64, MOVZ_I_D64, SLT, SLTu, SLTi, SLTiu>,
+       INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
+defm : MovzPats0<GPR64, FGR64, MOVZ_I_D64, SLT64, SLTu64, SLTi64, SLTiu64>,
+       INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
+defm : MovzPats1<GPR32, FGR64, MOVZ_I_D64, XOR>, INSN_MIPS4_32_NOT_32R6_64R6,
+       FGR_64;
+defm : MovzPats1<GPR64, FGR64, MOVZ_I64_D64, XOR64>,
+       INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
 defm : MovnPats<GPR32, FGR64, MOVN_I_D64, XOR>, INSN_MIPS4_32_NOT_32R6_64R6,
        FGR_64;
-
-defm : MovnPats<GPR32, GPR32, MOVN_I_I, XOR, i64>, INSN_MIPS4_32_NOT_32R6_64R6,
-       GPR_64;
-defm : MovnPats<GPR32, GPR64, MOVN_I_I64, XOR, i64>,
-       INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovnPats<GPR32, FGR32, MOVN_I_S, XOR, i64>, INSN_MIPS4_32_NOT_32R6_64R6,
-       GPR_64;
-defm : MovnPats<GPR32, AFGR64, MOVN_I_D32, XOR, i64>,
-       INSN_MIPS4_32_NOT_32R6_64R6, FGR_32;
-defm : MovnPats<GPR32, FGR64, MOVN_I_D64, XOR, i64>,
-       INSN_MIPS4_32_NOT_32R6_64R6, GPR_64, FGR_64;
-
-defm : MovnPats<GPR64, GPR32, MOVN_I64_I, XOR64, i64>,
-       INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovnPats<GPR64, GPR64, MOVN_I64_I64, XOR64, i64>,
-       INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovnPats<GPR64, FGR32, MOVN_I64_S, XOR64, i64>,
-       INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
-defm : MovnPats<GPR64, FGR64, MOVN_I64_D64, XOR64, i64>,
-       INSN_MIPS4_32_NOT_32R6_64R6, GPR_64, FGR_64;
+defm : MovnPats<GPR64, FGR64, MOVN_I64_D64, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
+       FGR_64;
 
 // For targets that don't have conditional-move instructions
 // we have to match SELECT nodes with pseudo instructions.
 let usesCustomInserter = 1 in {
-  class Select_Pseudo<RegisterOperand RC, RegisterOperand RO> :
-    PseudoSE<(outs RO:$dst), (ins RC:$cond, RO:$T, RO:$F),
-             [(set RO:$dst, (select RC:$cond, RO:$T, RO:$F))]>,
+  class Select_Pseudo<RegisterOperand RC> :
+    PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F),
+            [(set RC:$dst, (select GPR32Opnd:$cond, RC:$T, RC:$F))]>,
     ISA_MIPS1_NOT_4_32;
 
-  class SelectFP_Pseudo_T<RegisterOperand RO> :
-    PseudoSE<(outs RO:$dst), (ins GPR32Opnd:$cond, RO:$T, RO:$F),
-             [(set RO:$dst, (MipsCMovFP_T RO:$T, GPR32Opnd:$cond, RO:$F))]>,
+  class SelectFP_Pseudo_T<RegisterOperand RC> :
+    PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F),
+             [(set RC:$dst, (MipsCMovFP_T RC:$T, GPR32Opnd:$cond, RC:$F))]>,
     ISA_MIPS1_NOT_4_32;
 
-  class SelectFP_Pseudo_F<RegisterOperand RO> :
-    PseudoSE<(outs RO:$dst), (ins GPR32Opnd:$cond, RO:$T, RO:$F),
-             [(set RO:$dst, (MipsCMovFP_F RO:$T, GPR32Opnd:$cond, RO:$F))]>,
+  class SelectFP_Pseudo_F<RegisterOperand RC> :
+    PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F),
+             [(set RC:$dst, (MipsCMovFP_F RC:$T, GPR32Opnd:$cond, RC:$F))]>,
     ISA_MIPS1_NOT_4_32;
 }
 
-def PseudoSELECT_I : Select_Pseudo<GPR32Opnd, GPR32Opnd>;
-def PseudoSELECT_I64 : Select_Pseudo<GPR32Opnd, GPR64Opnd>;
-def PseudoSELECT_S : Select_Pseudo<GPR32Opnd, FGR32Opnd>;
-def PseudoSELECT_D32 : Select_Pseudo<GPR32Opnd, AFGR64Opnd>, FGR_32;
-def PseudoSELECT_D64 : Select_Pseudo<GPR32Opnd, FGR64Opnd>, FGR_64;
-
-def PseudoSELECT64_I : Select_Pseudo<GPR64Opnd, GPR32Opnd>, GPR_64;
-def PseudoSELECT64_I64 : Select_Pseudo<GPR64Opnd, GPR64Opnd>, GPR_64;
-def PseudoSELECT64_S : Select_Pseudo<GPR64Opnd, FGR32Opnd>, GPR_64;
-def PseudoSELECT64_D32 : Select_Pseudo<GPR64Opnd, AFGR64Opnd>, GPR_64, FGR_32;
-def PseudoSELECT64_D64 : Select_Pseudo<GPR64Opnd, FGR64Opnd>, GPR_64, FGR_64;
+def PseudoSELECT_I : Select_Pseudo<GPR32Opnd>;
+def PseudoSELECT_I64 : Select_Pseudo<GPR64Opnd>;
+def PseudoSELECT_S : Select_Pseudo<FGR32Opnd>;
+def PseudoSELECT_D32 : Select_Pseudo<AFGR64Opnd>, FGR_32;
+def PseudoSELECT_D64 : Select_Pseudo<FGR64Opnd>, FGR_64;
 
 def PseudoSELECTFP_T_I : SelectFP_Pseudo_T<GPR32Opnd>;
 def PseudoSELECTFP_T_I64 : SelectFP_Pseudo_T<GPR64Opnd>;
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 1c4a544..694ff9b 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -265,8 +265,7 @@
   // Without this, every float setcc comes with a AND/OR with the result,
   // we don't want this, since the fpcmp result goes to a flag register,
   // which is used implicitly by brcond and select operations.
-  AddPromotedToType(ISD::SETCC, MVT::i1,
-                    ABI.AreGprs64bit() ? MVT::i64 : MVT::i32);
+  AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
 
   // Mips Custom Operations
   setOperationAction(ISD::BR_JT,              MVT::Other, Custom);
@@ -463,10 +462,9 @@
 
 EVT MipsTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
                                            EVT VT) const {
-  if (VT.isVector())
-    return VT.changeVectorElementTypeToInteger();
-
-  return ABI.AreGprs64bit() ? MVT::i64 : MVT::i32;
+  if (!VT.isVector())
+    return MVT::i32;
+  return VT.changeVectorElementTypeToInteger();
 }
 
 static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG,
@@ -629,19 +627,19 @@
   if (!TrueC || !True.getValueType().isInteger())
     return SDValue();
 
+  // We'll also ignore MVT::i64 operands as this optimizations proves
+  // to be ineffective because of the required sign extensions as the result
+  // of a SETCC operator is always MVT::i32 for non-vector types.
+  if (True.getValueType() == MVT::i64)
+    return SDValue();
+
   int64_t Diff = TrueC->getSExtValue() - FalseC->getSExtValue();
 
   // 1)  (a < x) ? y : y-1
   //  slti $reg1, a, x
   //  addiu $reg2, $reg1, y-1
-  if (Diff == 1) {
-    if (SetCC.getValueType().getSizeInBits() >
-        False.getValueType().getSizeInBits())
-      SetCC = DAG.getNode(ISD::TRUNCATE, DL, False.getValueType(), SetCC);
-
-    SDValue Ret = DAG.getNode(ISD::ADD, DL, False.getValueType(), SetCC, False);
-    return Ret;
-  }
+  if (Diff == 1)
+    return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, False);
 
   // 2)  (a < x) ? y-1 : y
   //  slti $reg1, a, x
@@ -651,11 +649,6 @@
     ISD::CondCode CC = cast<CondCodeSDNode>(SetCC.getOperand(2))->get();
     SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0),
                          SetCC.getOperand(1), ISD::getSetCCInverse(CC, true));
-
-    if (SetCC.getValueType().getSizeInBits() >
-        True.getValueType().getSizeInBits())
-      SetCC = DAG.getNode(ISD::TRUNCATE, DL, True.getValueType(), SetCC);
-
     return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, True);
   }
 
@@ -1034,30 +1027,19 @@
     return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true);
   case Mips::SEL_D:
     return emitSEL_D(MI, BB);
-  case Mips::SEL64_S:
-    return emitSEL64_S(MI, BB);
 
   case Mips::PseudoSELECT_I:
   case Mips::PseudoSELECT_I64:
   case Mips::PseudoSELECT_S:
   case Mips::PseudoSELECT_D32:
   case Mips::PseudoSELECT_D64:
-  // 64-bit version
-  case Mips::PseudoSELECT64_I:
-  case Mips::PseudoSELECT64_I64:
-  case Mips::PseudoSELECT64_S:
-  case Mips::PseudoSELECT64_D32:
-  case Mips::PseudoSELECT64_D64:
-    return emitPseudoSELECT(MI, BB, false,
-                            Subtarget.isGP32bit() ? Mips::BNE : Mips::BNE64);
-
+    return emitPseudoSELECT(MI, BB, false, Mips::BNE);
   case Mips::PseudoSELECTFP_F_I:
   case Mips::PseudoSELECTFP_F_I64:
   case Mips::PseudoSELECTFP_F_S:
   case Mips::PseudoSELECTFP_F_D32:
   case Mips::PseudoSELECTFP_F_D64:
     return emitPseudoSELECT(MI, BB, true, Mips::BC1F);
-
   case Mips::PseudoSELECTFP_T_I:
   case Mips::PseudoSELECTFP_T_I64:
   case Mips::PseudoSELECTFP_T_S:
@@ -1592,30 +1574,6 @@
   return BB;
 }
 
-MachineBasicBlock *
-MipsTargetLowering::emitSEL64_S(MachineInstr *MI, MachineBasicBlock *BB) const {
-  MachineFunction *MF = BB->getParent();
-  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
-  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
-  MachineRegisterInfo &RegInfo = MF->getRegInfo();
-  DebugLoc DL = MI->getDebugLoc();
-  MachineBasicBlock::iterator II(MI);
-
-  unsigned Fc64 = MI->getOperand(1).getReg();
-
-  const auto &FGR32RegClass = TRI->getRegClass(Mips::FGR32RegClassID);
-  unsigned Fc32 = RegInfo.createVirtualRegister(FGR32RegClass);
-
-  BuildMI(*BB, II, DL, TII->get(Mips::COPY), Fc32)
-      .addReg(Fc64, 0, Mips::sub_lo);
-
-  // We don't erase the original instruction, we just replace the condition
-  // register with the 32-bit sub-register.
-  MI->getOperand(1).setReg(Fc32);
-
-  return BB;
-}
-
 //===----------------------------------------------------------------------===//
 //  Misc Lower Operation implementation
 //===----------------------------------------------------------------------===//
@@ -1697,10 +1655,8 @@
          "Floating point operand expected.");
 
   SDLoc DL(Op);
-  EVT VT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
-                              Op.getValueType());
-  SDValue True = DAG.getConstant(1, DL, VT);
-  SDValue False = DAG.getConstant(0, DL, VT);
+  SDValue True  = DAG.getConstant(1, DL, MVT::i32);
+  SDValue False = DAG.getConstant(0, DL, MVT::i32);
 
   return createCMovFP(DAG, Cond, True, False, DL);
 }
@@ -3954,9 +3910,9 @@
   } else {
     // bne rs, $0, sinkMBB
     BuildMI(BB, DL, TII->get(Opc))
-        .addReg(MI->getOperand(1).getReg())
-        .addReg(ABI.GetZeroReg())
-        .addMBB(sinkMBB);
+      .addReg(MI->getOperand(1).getReg())
+      .addReg(Mips::ZERO)
+      .addMBB(sinkMBB);
   }
 
   //  copy0MBB:
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index e46dfc1..0dc683e 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -444,8 +444,6 @@
                                  bool IsSRA) const;
     SDValue lowerADD(SDValue Op, SelectionDAG &DAG) const;
     SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
-    SDValue lowerATOMIC_CMP_SWAP_WITH_SUCCESS(SDValue Op,
-                                              SelectionDAG &DAG) const;
 
     /// isEligibleForTailCallOptimization - Check whether the call is eligible
     /// for tail call optimization.
@@ -579,10 +577,6 @@
     MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr *MI,
                                   MachineBasicBlock *BB, unsigned Size) const;
     MachineBasicBlock *emitSEL_D(MachineInstr *MI, MachineBasicBlock *BB) const;
-
-    MachineBasicBlock *emitSEL64_S(MachineInstr *MI,
-                                   MachineBasicBlock *BB) const;
-
     MachineBasicBlock *emitPseudoSELECT(MachineInstr *MI,
                                         MachineBasicBlock *BB, bool isFPCmp,
                                         unsigned Opc) const;
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index 59f3054..a6949fa 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -1035,18 +1035,17 @@
 }
 
 // SetCC
-class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RD,
-              RegisterOperand RO> :
-  InstSE<(outs RD:$rd), (ins RO:$rs, RO:$rt),
+class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
+  InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
          !strconcat(opstr, "\t$rd, $rs, $rt"),
-         [(set RD:$rd, (cond_op RO:$rs, RO:$rt))],
+         [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
          II_SLT_SLTU, FrmR, opstr>;
 
 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
-              RegisterOperand RD, RegisterOperand RO>:
-  InstSE<(outs RD:$rt), (ins RO:$rs, Od:$imm16),
+              RegisterOperand RO>:
+  InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
          !strconcat(opstr, "\t$rt, $rs, $imm16"),
-         [(set RD:$rt, (cond_op RO:$rs, imm_type:$imm16))],
+         [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
          II_SLTI_SLTIU, FrmI, opstr>;
 
 // Jump
@@ -1427,10 +1426,10 @@
 }
 def ADDi  : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>,
             ISA_MIPS1_NOT_32R6_64R6;
-def SLTi  : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd,
-            GPR32Opnd>, SLTI_FM<0xa>;
-def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd,
-            GPR32Opnd>, SLTI_FM<0xb>;
+def SLTi  : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
+            SLTI_FM<0xa>;
+def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
+            SLTI_FM<0xb>;
 let AdditionalPredicates = [NotInMicroMips] in {
 def ANDi  : MMRel, StdMMR6Rel,
             ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
@@ -1455,8 +1454,8 @@
             ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
 def ADD   : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
 def SUB   : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
-def SLT   : MMRel, SetCC_R<"slt", setlt, GPR32Opnd, GPR32Opnd>, ADD_FM<0, 0x2a>;
-def SLTu  : MMRel, SetCC_R<"sltu", setult, GPR32Opnd, GPR32Opnd>, ADD_FM<0, 0x2b>;
+def SLT   : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
+def SLTu  : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
 let AdditionalPredicates = [NotInMicroMips] in {
 def AND   : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
             ADD_FM<0, 0x24>;
@@ -2242,40 +2241,37 @@
 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
 
 // brcond patterns
-multiclass BrcondPats1<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
-                       Register ZEROReg, ValueType VT> {
-def : MipsPat<(brcond (VT (setne RC:$lhs, 0)), bb:$dst),
+multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
+                      Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
+                      Instruction SLTiuOp, Register ZEROReg> {
+def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
               (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
-def : MipsPat<(brcond (VT (seteq RC:$lhs, 0)), bb:$dst),
+def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
               (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
+
+def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
+              (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
+def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
+              (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
+def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
+              (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
+def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
+              (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
+def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
+              (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
+def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
+              (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
+
+def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
+              (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
+def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
+              (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
+
 def : MipsPat<(brcond RC:$cond, bb:$dst),
               (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
 }
 
-multiclass BrcondPats2<RegisterClass RC, Instruction BEQOp, Register ZEROReg,
-                       Instruction SLTOp, Instruction SLTuOp,
-                       Instruction SLTiOp, Instruction SLTiuOp,
-                       ValueType VT> {
-def : MipsPat<(brcond (VT (setge RC:$lhs, RC:$rhs)), bb:$dst),
-              (BEQOp (SLTOp RC:$lhs, RC:$rhs), ZEROReg, bb:$dst)>;
-def : MipsPat<(brcond (VT (setuge RC:$lhs, RC:$rhs)), bb:$dst),
-              (BEQOp (SLTuOp RC:$lhs, RC:$rhs), ZEROReg, bb:$dst)>;
-def : MipsPat<(brcond (VT (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
-              (BEQOp (SLTiOp RC:$lhs, immSExt16:$rhs), ZEROReg, bb:$dst)>;
-def : MipsPat<(brcond (VT (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
-              (BEQOp (SLTiuOp RC:$lhs, immSExt16:$rhs), ZEROReg, bb:$dst)>;
-def : MipsPat<(brcond (VT (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
-              (BEQOp (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZEROReg, bb:$dst)>;
-def : MipsPat<(brcond (VT (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
-              (BEQOp (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZEROReg, bb:$dst)>;
-def : MipsPat<(brcond (VT (setle RC:$lhs, RC:$rhs)), bb:$dst),
-              (BEQOp (SLTOp RC:$rhs, RC:$lhs), ZEROReg, bb:$dst)>;
-def : MipsPat<(brcond (VT (setule RC:$lhs, RC:$rhs)), bb:$dst),
-              (BEQOp (SLTuOp RC:$rhs, RC:$lhs), ZEROReg, bb:$dst)>;
-}
-
-defm : BrcondPats1<GPR32, BEQ, BNE, ZERO, i32>;
-defm : BrcondPats2<GPR32, BEQ, ZERO, SLT, SLTu, SLTi, SLTiu, i32>;
+defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
 
 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
               (BLEZ i32:$lhs, bb:$dst)>;
@@ -2295,12 +2291,11 @@
                 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
 }
 
-multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp,
-                     Instruction XORiOp> {
+multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
   def : MipsPat<(setle RC:$lhs, RC:$rhs),
-                (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
+                (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
   def : MipsPat<(setule RC:$lhs, RC:$rhs),
-                (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
+                (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
 }
 
 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
@@ -2310,27 +2305,26 @@
                 (SLTuOp RC:$rhs, RC:$lhs)>;
 }
 
-multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp,
-                     Instruction XORiOp> {
+multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
   def : MipsPat<(setge RC:$lhs, RC:$rhs),
-                (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
+                (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
   def : MipsPat<(setuge RC:$lhs, RC:$rhs),
-                (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
+                (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
 }
 
 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
-                        Instruction SLTiuOp, Instruction XORiOp> {
+                        Instruction SLTiuOp> {
   def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
-                (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
+                (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
   def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
-                (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
+                (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
 }
 
 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
-defm : SetlePats<GPR32, SLT, SLTu, XORi>;
+defm : SetlePats<GPR32, SLT, SLTu>;
 defm : SetgtPats<GPR32, SLT, SLTu>;
-defm : SetgePats<GPR32, SLT, SLTu, XORi>;
-defm : SetgeImmPats<GPR32, SLTi, SLTiu, XORi>;
+defm : SetgePats<GPR32, SLT, SLTu>;
+defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
 
 // bswap pattern
 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td
index c58965e..02bcac5 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.td
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td
@@ -391,9 +391,8 @@
           Unallocatable;
 
 // MIPS32r6/MIPS64r6 store FPU condition codes in normal FGR registers.
-// These classes allow us to represent this in codegen patterns.
-def FGRCC32 : RegisterClass<"Mips", [i32], 32, (sequence "F%u", 0, 31)>;
-def FGRCC64 : RegisterClass<"Mips", [i64], 64, (sequence "D%u_64", 0, 31)>;
+// This class allows us to represent this in codegen patterns.
+def FGRCC : RegisterClass<"Mips", [i32], 32, (sequence "F%u", 0, 31)>;
 
 def MSA128B: RegisterClass<"Mips", [v16i8], 128,
                            (sequence "W%u", 0, 31)>;
@@ -596,13 +595,7 @@
   let ParserMatchClass = FGR32AsmOperand;
 }
 
-def FGRCC32Opnd : RegisterOperand<FGRCC32> {
-  // The assembler doesn't use register classes so we can re-use
-  // FGR32AsmOperand.
-  let ParserMatchClass = FGR32AsmOperand;
-}
-
-def FGRCC64Opnd : RegisterOperand<FGRCC64> {
+def FGRCCOpnd : RegisterOperand<FGRCC> {
   // The assembler doesn't use register classes so we can re-use
   // FGR32AsmOperand.
   let ParserMatchClass = FGR32AsmOperand;
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index 3731654..6f001ea 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -251,14 +251,28 @@
   SDValue LHS = Node->getOperand(0), RHS = Node->getOperand(1);
   EVT VT = LHS.getValueType();
 
+  SDNode *Carry = CurDAG->getMachineNode(SLTuOp, DL, VT, Ops);
+
+  if (Subtarget->isGP64bit()) {
+    // On 64-bit targets, sltu produces an i64 but our backend currently says
+    // that SLTu64 produces an i32. We need to fix this in the long run but for
+    // now, just make the DAG type-correct by asserting the upper bits are zero.
+    Carry = CurDAG->getMachineNode(Mips::SUBREG_TO_REG, DL, VT,
+                                   CurDAG->getTargetConstant(0, DL, VT),
+                                   SDValue(Carry, 0),
+                                   CurDAG->getTargetConstant(Mips::sub_32, DL,
+                                                             VT));
+  }
+
   // Generate a second addition only if we know that RHS is not a
   // constant-zero node.
-  SDNode *Carry = CurDAG->getMachineNode(SLTuOp, DL, VT, Ops);
+  SDNode *AddCarry = Carry;
   ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS);
   if (!C || C->getZExtValue())
-    Carry = CurDAG->getMachineNode(ADDuOp, DL, VT, SDValue(Carry, 0), RHS);
+    AddCarry = CurDAG->getMachineNode(ADDuOp, DL, VT, SDValue(Carry, 0), RHS);
 
-  return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS, SDValue(Carry, 0));
+  return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS,
+                              SDValue(AddCarry, 0));
 }
 
 /// Match frameindex
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index 790b8cb..e040b78 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -1292,6 +1292,7 @@
   return DAG.getMergeValues(Vals, DL);
 }
 
+
 static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
   SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
                              DAG.getConstant(0, DL, MVT::i32));