Index: llvm/trunk/include/llvm/CodeGen/MachineInstr.h
===================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineInstr.h
+++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h
@@ -547,6 +547,12 @@
     return hasProperty(MCID::MoveImm, Type);
   }
 
+  /// Return true if this instruction is a register move.
+  /// (including moving values from subreg to reg)
+  bool isMoveReg(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::MoveReg, Type);
+  }
+
   /// Return true if this instruction is a bitcast instruction.
   bool isBitcast(QueryType Type = IgnoreBundle) const {
     return hasProperty(MCID::Bitcast, Type);
Index: llvm/trunk/include/llvm/CodeGen/TargetInstrInfo.h
===================================================================
--- llvm/trunk/include/llvm/CodeGen/TargetInstrInfo.h
+++ llvm/trunk/include/llvm/CodeGen/TargetInstrInfo.h
@@ -845,6 +845,14 @@
     llvm_unreachable("Target didn't implement TargetInstrInfo::copyPhysReg!");
   }
 
+  /// If the specific machine instruction is a instruction that moves/copies
+  /// value from one register to another register return true along with
+  /// @Source machine operand and @Destination machine operand.
+  virtual bool isCopyInstr(const MachineInstr &MI, MachineOperand &Source,
+                           MachineOperand &Destination) const {
+    return false;
+  }
+
   /// Store the specified register of the given register class to the specified
   /// stack frame index. The store instruction is to be added to the given
   /// machine basic block before the specified machine instruction. If isKill
Index: llvm/trunk/include/llvm/MC/MCInstrDesc.h
===================================================================
--- llvm/trunk/include/llvm/MC/MCInstrDesc.h
+++ llvm/trunk/include/llvm/MC/MCInstrDesc.h
@@ -127,6 +127,7 @@
   IndirectBranch,
   Compare,
   MoveImm,
+  MoveReg,
   Bitcast,
   Select,
   DelaySlot,
@@ -244,6 +245,9 @@
   /// Return true if the instruction is an add instruction.
   bool isAdd() const { return Flags & (1ULL << MCID::Add); }
 
+  /// Return true if the instruction is a register to register move.
+  bool isMoveReg() const { return Flags & (1ULL << MCID::MoveReg); }
+
   ///  Return true if the instruction is a call.
   bool isCall() const { return Flags & (1ULL << MCID::Call); }
 
Index: llvm/trunk/include/llvm/Target/Target.td
===================================================================
--- llvm/trunk/include/llvm/Target/Target.td
+++ llvm/trunk/include/llvm/Target/Target.td
@@ -437,6 +437,7 @@
   bit isIndirectBranch = 0; // Is this instruction an indirect branch?
   bit isCompare    = 0;     // Is this instruction a comparison instruction?
   bit isMoveImm    = 0;     // Is this instruction a move immediate instruction?
+  bit isMoveReg    = 0;     // Is this instruction a move register instruction?
   bit isBitcast    = 0;     // Is this instruction a bitcast instruction?
   bit isSelect     = 0;     // Is this instruction a select instruction?
   bit isBarrier    = 0;     // Can control flow fall through this instruction?
Index: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
===================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
+++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -201,6 +201,9 @@
                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
                    bool KillSrc) const override;
 
+  bool isCopyInstr(const MachineInstr &MI, MachineOperand &Src,
+                   MachineOperand &Dest) const override;
+
   void storeRegToStackSlot(MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator MBBI,
                            unsigned SrcReg, bool isKill, int FrameIndex,
Index: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
===================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -935,6 +935,24 @@
     Mov->addRegisterKilled(SrcReg, TRI);
 }
 
+bool ARMBaseInstrInfo::isCopyInstr(const MachineInstr &MI, MachineOperand &Src,
+                                   MachineOperand &Dest) const {
+  // VMOVRRD is also a copy instruction but it requires
+  // special way of handling. It is more complex copy version
+  // and since that we are not considering it. For recognition
+  // of such instruction isExtractSubregLike MI interface fuction
+  // could be used.
+  // VORRq is considered as a move only if two inputs are
+  // the same register.
+  if (!MI.isMoveReg() ||
+      (MI.getOpcode() == ARM::VORRq &&
+       MI.getOperand(1).getReg() != MI.getOperand(2).getReg()))
+    return false;
+  Dest = MI.getOperand(0);
+  Src = MI.getOperand(1);
+  return true;
+}
+
 const MachineInstrBuilder &
 ARMBaseInstrInfo::AddDReg(MachineInstrBuilder &MIB, unsigned Reg,
                           unsigned SubIdx, unsigned State,
Index: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
@@ -3340,7 +3340,7 @@
 //  Move Instructions.
 //
 
-let hasSideEffects = 0 in
+let hasSideEffects = 0, isMoveReg = 1 in
 def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
                 "mov", "\t$Rd, $Rm", []>, UnaryDP, Sched<[WriteALU]> {
   bits<4> Rd;
Index: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
===================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
@@ -1154,7 +1154,7 @@
 
 // A7-73: MOV(2) - mov setting flag.
 
-let hasSideEffects = 0 in {
+let hasSideEffects = 0, isMoveReg = 1 in {
 def tMOVr : Thumb1pI<(outs GPR:$Rd), (ins GPR:$Rm), AddrModeNone,
                       2, IIC_iMOVr,
                       "mov", "\t$Rd, $Rm", "", []>,
Index: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
===================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
+++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
@@ -999,6 +999,7 @@
                   []>;
 
 let hasSideEffects = 0 in {
+let isMoveReg = 1 in {
 def VMOVD  : ADuI<0b11101, 0b11, 0b0000, 0b01, 0,
                   (outs DPR:$Dd), (ins DPR:$Dm),
                   IIC_fpUNA64, "vmov", ".f64\t$Dd, $Dm", []>;
@@ -1006,6 +1007,7 @@
 def VMOVS  : ASuI<0b11101, 0b11, 0b0000, 0b01, 0,
                   (outs SPR:$Sd), (ins SPR:$Sm),
                   IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm", []>;
+} // isMoveReg
 
 let PostEncoderMethod = "", DecoderNamespace = "VFPV8" in {
 def VMOVH  : ASuInp<0b11101, 0b11, 0b0000, 0b01, 0,
@@ -1024,6 +1026,7 @@
 // FP <-> GPR Copies.  Int <-> FP Conversions.
 //
 
+let isMoveReg = 1 in {
 def VMOVRS : AVConv2I<0b11100001, 0b1010,
                       (outs GPR:$Rt), (ins SPR:$Sn),
                       IIC_fpMOVSI, "vmov", "\t$Rt, $Sn",
@@ -1069,6 +1072,7 @@
   // pipelines.
   let D = VFPNeonDomain;
 }
+} // isMoveReg
 def : Pat<(arm_vmovsr GPR:$Rt), (VMOVSR GPR:$Rt)>, Requires<[HasVFP2, UseVMOVSR]>;
 
 let hasSideEffects = 0 in {
Index: llvm/trunk/lib/Target/Mips/MicroMipsDSPInstrInfo.td
===================================================================
--- llvm/trunk/lib/Target/Mips/MicroMipsDSPInstrInfo.td
+++ llvm/trunk/lib/Target/Mips/MicroMipsDSPInstrInfo.td
@@ -386,6 +386,7 @@
   string AsmString = !strconcat("wrdsp", "\t$rt, $mask");
   list<dag> Pattern = [(int_mips_wrdsp GPR32Opnd:$rt, immZExt7:$mask)];
   InstrItinClass Itinerary = NoItinerary;
+  bit isMoveReg = 1;
 }
 
 class BPOSGE32C_MMR3_DESC {
Index: llvm/trunk/lib/Target/Mips/MicroMipsInstrFPU.td
===================================================================
--- llvm/trunk/lib/Target/Mips/MicroMipsInstrFPU.td
+++ llvm/trunk/lib/Target/Mips/MicroMipsInstrFPU.td
@@ -130,7 +130,9 @@
 }
 
 def FMOV_S_MM : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>,
-                ABS_FM_MM<0, 0x1>, ISA_MICROMIPS;
+                ABS_FM_MM<0, 0x1>, ISA_MICROMIPS {
+  let isMoveReg = 1;
+}
 def FNEG_S_MM : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>,
                 ABS_FM_MM<0, 0x2d>, ISA_MICROMIPS;
 
Index: llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td
===================================================================
--- llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td
+++ llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td
@@ -238,6 +238,7 @@
                  !strconcat(opstr, "\t$dst_regs, $rs, $rt"), [],
                  NoItinerary, FrmR> {
   let isReMaterializable = 1;
+  let isMoveReg = 1;
 }
 
 /// A register pair used by load/store pair instructions.
@@ -415,12 +416,14 @@
   [], II_MFHI_MFLO, FrmR> {
   let Uses = [UseReg];
   let hasSideEffects = 0;
+  let isMoveReg = 1;
 }
 
 class MoveMM16<string opstr, RegisterOperand RO>
     :  MicroMipsInst16<(outs RO:$rd), (ins RO:$rs),
                        !strconcat(opstr, "\t$rd, $rs"), [], II_MOVE, FrmR> {
   let isReMaterializable = 1;
+  let isMoveReg = 1;
 }
 
 class LoadImmMM16<string opstr, Operand Od, RegisterOperand RO> :
Index: llvm/trunk/lib/Target/Mips/Mips16InstrInfo.h
===================================================================
--- llvm/trunk/lib/Target/Mips/Mips16InstrInfo.h
+++ llvm/trunk/lib/Target/Mips/Mips16InstrInfo.h
@@ -53,6 +53,9 @@
                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
                    bool KillSrc) const override;
 
+  bool isCopyInstr(const MachineInstr &MI, MachineOperand &Src,
+                   MachineOperand &Dest) const override;
+
   void storeRegToStack(MachineBasicBlock &MBB,
                        MachineBasicBlock::iterator MBBI,
                        unsigned SrcReg, bool isKill, int FrameIndex,
Index: llvm/trunk/lib/Target/Mips/Mips16InstrInfo.cpp
===================================================================
--- llvm/trunk/lib/Target/Mips/Mips16InstrInfo.cpp
+++ llvm/trunk/lib/Target/Mips/Mips16InstrInfo.cpp
@@ -97,6 +97,16 @@
     MIB.addReg(SrcReg, getKillRegState(KillSrc));
 }
 
+bool Mips16InstrInfo::isCopyInstr(const MachineInstr &MI, MachineOperand &Src,
+                                  MachineOperand &Dest) const {
+  if (MI.isMoveReg()) {
+    Dest = MI.getOperand(0);
+    Src = MI.getOperand(1);
+    return true;
+  }
+  return false;
+}
+
 void Mips16InstrInfo::storeRegToStack(MachineBasicBlock &MBB,
                                       MachineBasicBlock::iterator I,
                                       unsigned SrcReg, bool isKill, int FI,
Index: llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td
===================================================================
--- llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td
+++ llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td
@@ -869,7 +869,9 @@
 //Purpose: Move
 // To move the contents of a GPR to a GPR.
 //
-def MoveR3216: FI8_MOVR3216_ins<"move", IIM16Alu>;
+def MoveR3216: FI8_MOVR3216_ins<"move", IIM16Alu> {
+  let isMoveReg = 1;
+}
 
 //
 // Format: MFHI rx MIPS16e
@@ -879,6 +881,7 @@
 def Mfhi16: FRR16_M_ins<0b10000, "mfhi", IIM16Alu> {
   let Uses = [HI0];
   let hasSideEffects = 0;
+  let isMoveReg = 1;
 }
 
 //
@@ -889,6 +892,7 @@
 def Mflo16: FRR16_M_ins<0b10010, "mflo", IIM16Alu> {
   let Uses = [LO0];
   let hasSideEffects = 0;
+  let isMoveReg = 0;
 }
 
 //
Index: llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td
===================================================================
--- llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td
+++ llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td
@@ -377,10 +377,12 @@
 let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
   def DSLL64_32 : FR<0x00, 0x3c, (outs GPR64:$rd), (ins GPR32:$rt),
                      "dsll\t$rd, $rt, 32", [], II_DSLL>;
-  def SLL64_32 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR32:$rt),
-                    "sll\t$rd, $rt, 0", [], II_SLL>;
-  def SLL64_64 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR64:$rt),
-                    "sll\t$rd, $rt, 0", [], II_SLL>;
+  let isMoveReg = 1 in {
+    def SLL64_32 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR32:$rt),
+                      "sll\t$rd, $rt, 0", [], II_SLL>;
+    def SLL64_64 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR64:$rt),
+                      "sll\t$rd, $rt, 0", [], II_SLL>;
+  }
 }
 
 // We need the following pseudo instruction to avoid offset calculation for
Index: llvm/trunk/lib/Target/Mips/MipsDSPInstrInfo.td
===================================================================
--- llvm/trunk/lib/Target/Mips/MipsDSPInstrInfo.td
+++ llvm/trunk/lib/Target/Mips/MipsDSPInstrInfo.td
@@ -447,6 +447,7 @@
   list<dag> Pattern = [(set GPR32Opnd:$rd, (OpNode immZExt10:$mask))];
   InstrItinClass Itinerary = itin;
   string BaseOpcode = instr_asm;
+  bit isMoveReg = 1;
 }
 
 class WRDSP_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
@@ -457,6 +458,7 @@
   list<dag> Pattern = [(OpNode GPR32Opnd:$rs, immZExt10:$mask)];
   InstrItinClass Itinerary = itin;
   string BaseOpcode = instr_asm;
+  bit isMoveReg = 1;
 }
 
 class DPA_W_PH_DESC_BASE<string instr_asm, SDPatternOperator OpNode> {
@@ -500,6 +502,7 @@
   list<dag> Pattern = [(set GPR32Opnd:$rd, (OpNode RO:$ac))];
   InstrItinClass Itinerary = itin;
   string BaseOpcode = instr_asm;
+  bit isMoveReg = 1;
 }
 
 class MTHI_DESC_BASE<string instr_asm, RegisterOperand RO, InstrItinClass itin> {
@@ -508,6 +511,7 @@
   string AsmString = !strconcat(instr_asm, "\t$rs, $ac");
   InstrItinClass Itinerary = itin;
   string BaseOpcode = instr_asm;
+  bit isMoveReg = 1;
 }
 
 class BPOSGE32_PSEUDO_DESC_BASE<SDPatternOperator OpNode, InstrItinClass itin> :
Index: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td
===================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrFPU.td
+++ llvm/trunk/lib/Target/Mips/MipsInstrFPU.td
@@ -149,12 +149,16 @@
 class MFC1_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
               InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
   InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"),
-         [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR, opstr>, HARDFLOAT;
+         [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR, opstr>, HARDFLOAT {
+  let isMoveReg = 1;
+}
 
 class MTC1_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
               InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
   InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"),
-         [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR, opstr>, HARDFLOAT;
+         [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR, opstr>, HARDFLOAT {
+  let isMoveReg = 1;
+}
 
 class MTC1_64_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
                  InstrItinClass Itin> :
@@ -510,14 +514,16 @@
               bitconvert>, MFC1_FM<5>, ISA_MIPS3;
   def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64Opnd, II_DMFC1,
                       bitconvert>, MFC1_FM<1>, ISA_MIPS3;
-  def FMOV_S   : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>,
-                 ABSS_FM<0x6, 16>;
-  def FMOV_D32 : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, II_MOV_D>,
-                 ABSS_FM<0x6, 17>, FGR_32;
-  def FMOV_D64 : ABSS_FT<"mov.d", FGR64Opnd, FGR64Opnd, II_MOV_D>,
-                 ABSS_FM<0x6, 17>, FGR_64 {
-                   let DecoderNamespace = "MipsFP64";
-  }
+  let isMoveReg = 1 in {
+    def FMOV_S   : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>,
+                   ABSS_FM<0x6, 16>;
+    def FMOV_D32 : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, II_MOV_D>,
+                   ABSS_FM<0x6, 17>, FGR_32;
+    def FMOV_D64 : ABSS_FT<"mov.d", FGR64Opnd, FGR64Opnd, II_MOV_D>,
+                   ABSS_FM<0x6, 17>, FGR_64 {
+                     let DecoderNamespace = "MipsFP64";
+    }
+  } // isMoveReg
 }
 
 /// Floating Point Memory Instructions
Index: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
===================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
@@ -1772,6 +1772,7 @@
          FrmR, opstr> {
   let Uses = [UseReg];
   let hasSideEffects = 0;
+  let isMoveReg = 1;
 }
 
 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
@@ -1784,6 +1785,7 @@
   FrmR, opstr> {
   let Defs = DefRegs;
   let hasSideEffects = 0;
+  let isMoveReg = 1;
 }
 
 class EffectiveAddress<string opstr, RegisterOperand RO> :
Index: llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
===================================================================
--- llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
+++ llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
@@ -1790,6 +1790,7 @@
   string AsmString = "cfcmsa\t$rd, $cs";
   InstrItinClass Itinerary = NoItinerary;
   bit hasSideEffects = 1;
+  bit isMoveReg = 1;
 }
 
 class CLE_S_B_DESC : MSA_3R_DESC_BASE<"cle_s.b", vsetle_v16i8, MSA128BOpnd>;
@@ -1884,6 +1885,7 @@
   string AsmString = "ctcmsa\t$cd, $rs";
   InstrItinClass Itinerary = NoItinerary;
   bit hasSideEffects = 1;
+  bit isMoveReg = 1;
 }
 
 class DIV_S_B_DESC : MSA_3R_DESC_BASE<"div_s.b", sdiv, MSA128BOpnd>;
@@ -2429,6 +2431,7 @@
   string AsmString = "move.v\t$wd, $ws";
   list<dag> Pattern = [];
   InstrItinClass Itinerary = NoItinerary;
+  bit isMoveReg = 1;
 }
 
 class MSUB_Q_H_DESC : MSA_3RF_4RF_DESC_BASE<"msub_q.h", int_mips_msub_q_h,
Index: llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.h
===================================================================
--- llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.h
+++ llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.h
@@ -47,6 +47,9 @@
                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
                    bool KillSrc) const override;
 
+  bool isCopyInstr(const MachineInstr &MI, MachineOperand &Src,
+                   MachineOperand &Dest) const override;
+
   void storeRegToStack(MachineBasicBlock &MBB,
                        MachineBasicBlock::iterator MI,
                        unsigned SrcReg, bool isKill, int FrameIndex,
Index: llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.cpp
===================================================================
--- llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -179,6 +179,62 @@
     MIB.addReg(ZeroReg);
 }
 
+static bool isORCopyInst(const MachineInstr &MI) {
+  switch (MI.getOpcode()) {
+  case Mips::OR_MM:
+  case Mips::OR:
+    if (MI.getOperand(2).getReg() == Mips::ZERO)
+      return true;
+  case Mips::OR64:
+    if (MI.getOperand(2).getReg() == Mips::ZERO_64)
+      return true;
+  default:
+      return false;
+  }
+}
+
+/// If @MI is WRDSP/RRDSP instruction return true with @isWrite set to true
+/// if it is WRDSP instruction.
+static bool isReadOrWritToDSPReg(const MachineInstr &MI, bool &isWrite) {
+  switch (MI.getOpcode()) {
+    case Mips::WRDSP:
+    case Mips::WRDSP_MM:
+      isWrite = true;
+    case Mips::RDDSP:
+    case Mips::RDDSP_MM:
+      return true;
+    default:
+     return false;
+  }
+}
+
+/// We check for the common case of 'or', as it's MIPS' preferred instruction
+/// for GPRs but we have to check the operands to ensure that is the case.
+/// Other move instructions for MIPS are directly identifiable.
+bool MipsSEInstrInfo::isCopyInstr(const MachineInstr &MI, MachineOperand &Src,
+                                  MachineOperand &Dest) const {
+  bool isDSPControlWrite = false;
+  // Condition is made to match the creation of WRDSP/RDDSP copy instruction
+  // from copyPhysReg function.
+  if (isReadOrWritToDSPReg(MI, isDSPControlWrite)) {
+    if (!MI.getOperand(1).isImm() || !MI.getOperand(1).getImm() == (1<<4))
+      return false;
+    else if (isDSPControlWrite) {
+      Src = MI.getOperand(0);
+      Dest = MI.getOperand(2);
+    } else {
+      Dest = MI.getOperand(0);
+      Src = MI.getOperand(2);
+    }
+    return true;
+  } else if (MI.isMoveReg() || isORCopyInst(MI)) {
+    Dest = MI.getOperand(0);
+    Src = MI.getOperand(1);
+    return true;
+  }
+  return false;
+}
+
 void MipsSEInstrInfo::
 storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
                 unsigned SrcReg, bool isKill, int FI,
Index: llvm/trunk/lib/Target/X86/X86InstrAVX512.td
===================================================================
--- llvm/trunk/lib/Target/X86/X86InstrAVX512.td
+++ llvm/trunk/lib/Target/X86/X86InstrAVX512.td
@@ -2683,7 +2683,7 @@
 multiclass avx512_mask_mov<bits<8> opc_kk, bits<8> opc_km, bits<8> opc_mk,
                          string OpcodeStr, RegisterClass KRC,
                          ValueType vvt, X86MemOperand x86memop> {
-  let hasSideEffects = 0, SchedRW = [WriteMove] in
+  let isMoveReg = 1, hasSideEffects = 0, SchedRW = [WriteMove] in
   def kk : I<opc_kk, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
              !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>,
              Sched<[WriteMove]>;
@@ -3168,6 +3168,7 @@
                        X86SchedWriteMoveLS Sched, bit NoRMPattern = 0,
                        SDPatternOperator SelectOprr = vselect> {
   let hasSideEffects = 0 in {
+  let isMoveReg = 1 in
   def rr : AVX512PI<opc, MRMSrcReg, (outs _.RC:$dst), (ins _.RC:$src),
                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), [],
                     _.ExeDomain>, EVEX, Sched<[Sched.RR]>;
@@ -3270,6 +3271,7 @@
                         string Name, X86SchedWriteMoveLS Sched,
                         bit NoMRPattern = 0> {
   let hasSideEffects = 0 in {
+  let isMoveReg = 1 in
   def rr_REV  : AVX512PI<opc, MRMDestReg, (outs _.RC:$dst), (ins _.RC:$src),
                          OpcodeStr # ".s\t{$src, $dst|$dst, $src}",
                          [], _.ExeDomain>, EVEX, FoldGenData<Name#rr>,
Index: llvm/trunk/lib/Target/X86/X86InstrInfo.h
===================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.h
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.h
@@ -394,6 +394,8 @@
   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
                    bool KillSrc) const override;
+  bool isCopyInstr(const MachineInstr &MI, MachineOperand &Src,
+                   MachineOperand &Dest) const override;
   void storeRegToStackSlot(MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator MI, unsigned SrcReg,
                            bool isKill, int FrameIndex,
Index: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
===================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
@@ -6852,6 +6852,16 @@
   llvm_unreachable("Cannot emit physreg copy instruction");
 }
 
+bool X86InstrInfo::isCopyInstr(const MachineInstr &MI, MachineOperand &Src,
+                               MachineOperand &Dest) const {
+  if (MI.isMoveReg()) {
+    Dest = MI.getOperand(0);
+    Src = MI.getOperand(1);
+    return true;
+  }
+  return false;
+}
+
 static unsigned getLoadStoreRegOpcode(unsigned Reg,
                                       const TargetRegisterClass *RC,
                                       bool isStackAligned,
Index: llvm/trunk/lib/Target/X86/X86InstrInfo.td
===================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td
@@ -1455,7 +1455,7 @@
 //  Move Instructions.
 //
 let SchedRW = [WriteMove] in {
-let hasSideEffects = 0 in {
+let hasSideEffects = 0, isMoveReg = 1 in {
 def MOV8rr  : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
                 "mov{b}\t{$src, $dst|$dst, $src}", []>;
 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
@@ -1624,7 +1624,7 @@
 } // hasSideEffects = 0
 
 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
-    SchedRW = [WriteMove] in {
+    SchedRW = [WriteMove], isMoveReg = 1 in {
 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
                    "mov{b}\t{$src, $dst|$dst, $src}", []>,
                    FoldGenData<"MOV8rr">;
@@ -1673,7 +1673,7 @@
 // that they can be used for copying and storing h registers, which can't be
 // encoded when a REX prefix is present.
 let isCodeGenOnly = 1 in {
-let hasSideEffects = 0 in
+let hasSideEffects = 0, isMoveReg = 1 in
 def MOV8rr_NOREX : I<0x88, MRMDestReg,
                      (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
                      "mov{b}\t{$src, $dst|$dst, $src}", []>,
Index: llvm/trunk/lib/Target/X86/X86InstrMMX.td
===================================================================
--- llvm/trunk/lib/Target/X86/X86InstrMMX.td
+++ llvm/trunk/lib/Target/X86/X86InstrMMX.td
@@ -215,14 +215,14 @@
                                "movq\t{$src, $dst|$dst, $src}",
                                [(set GR64:$dst, (bitconvert VR64:$src))]>,
                                Sched<[WriteVecMoveToGpr]>;
-let SchedRW = [WriteVecMove], hasSideEffects = 0 in {
+let SchedRW = [WriteVecMove], hasSideEffects = 0, isMoveReg = 1 in {
 def MMX_MOVQ64rr : MMXI<0x6F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src),
                         "movq\t{$src, $dst|$dst, $src}", []>;
 let isCodeGenOnly = 1, ForceDisassemble = 1 in
 def MMX_MOVQ64rr_REV : MMXI<0x7F, MRMDestReg, (outs VR64:$dst), (ins VR64:$src),
                             "movq\t{$src, $dst|$dst, $src}", []>,
                             FoldGenData<"MMX_MOVQ64rr">;
-} // SchedRW, hasSideEffects
+} // SchedRW, hasSideEffects, isMoveReg
 } // isBitcast
 
 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayStore = 1 in
Index: llvm/trunk/lib/Target/X86/X86InstrSSE.td
===================================================================
--- llvm/trunk/lib/Target/X86/X86InstrSSE.td
+++ llvm/trunk/lib/Target/X86/X86InstrSSE.td
@@ -408,7 +408,7 @@
                             X86MemOperand x86memop, PatFrag ld_frag,
                             string asm, Domain d,
                             X86SchedWriteMoveLS sched> {
-let hasSideEffects = 0 in
+let hasSideEffects = 0, isMoveReg = 1 in
   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>,
            Sched<[sched.RR]>;
@@ -505,7 +505,8 @@
 } // Predicate
 
 // For disassembler
-let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
+let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
+    isMoveReg = 1 in {
 let SchedRW = [SchedWriteFMoveLS.XMM.RR] in {
   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
                           (ins VR128:$src),
@@ -581,7 +582,7 @@
 
 // For disassembler
 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
-    SchedRW = [SchedWriteFMoveLS.XMM.RR] in {
+    isMoveReg = 1, SchedRW = [SchedWriteFMoveLS.XMM.RR] in {
   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
                          "movaps\t{$src, $dst|$dst, $src}", []>,
                          FoldGenData<"MOVAPSrr">;
Index: llvm/trunk/utils/TableGen/CodeGenInstruction.h
===================================================================
--- llvm/trunk/utils/TableGen/CodeGenInstruction.h
+++ llvm/trunk/utils/TableGen/CodeGenInstruction.h
@@ -226,6 +226,7 @@
     bool isIndirectBranch : 1;
     bool isCompare : 1;
     bool isMoveImm : 1;
+    bool isMoveReg : 1;
     bool isBitcast : 1;
     bool isSelect : 1;
     bool isBarrier : 1;
Index: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
===================================================================
--- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
+++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
@@ -306,6 +306,7 @@
   isIndirectBranch = R->getValueAsBit("isIndirectBranch");
   isCompare    = R->getValueAsBit("isCompare");
   isMoveImm    = R->getValueAsBit("isMoveImm");
+  isMoveReg    = R->getValueAsBit("isMoveReg");
   isBitcast    = R->getValueAsBit("isBitcast");
   isSelect     = R->getValueAsBit("isSelect");
   isBarrier    = R->getValueAsBit("isBarrier");
Index: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
===================================================================
--- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
+++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
@@ -489,6 +489,7 @@
   if (Inst.isIndirectBranch)   OS << "|(1ULL<<MCID::IndirectBranch)";
   if (Inst.isCompare)          OS << "|(1ULL<<MCID::Compare)";
   if (Inst.isMoveImm)          OS << "|(1ULL<<MCID::MoveImm)";
+  if (Inst.isMoveReg)          OS << "|(1ULL<<MCID::MoveReg)";
   if (Inst.isBitcast)          OS << "|(1ULL<<MCID::Bitcast)";
   if (Inst.isAdd)              OS << "|(1ULL<<MCID::Add)";
   if (Inst.isSelect)           OS << "|(1ULL<<MCID::Select)";