Index: lib/Target/X86/X86InstrInfo.cpp =================================================================== --- lib/Target/X86/X86InstrInfo.cpp +++ lib/Target/X86/X86InstrInfo.cpp @@ -7682,6 +7682,22 @@ } } +static void ApplyRegClassConstraints(MachineFunction &MF, + const MCOperandInfo &OpInfo, + const MachineOperand &MO) { + const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); + if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) { + const TargetRegisterClass *RC; + uint8_t RegClass = OpInfo.RegClass; + if (OpInfo.isLookupPtrRegClass()) + RC = TRI->getPointerRegClass(MF, RegClass); + else + RC = TRI->getRegClass(RegClass); + + MF.getRegInfo().constrainRegClass(MO.getReg(), RC); + } +} + static MachineInstr *FuseTwoAddrInst(MachineFunction &MF, unsigned Opcode, ArrayRef MOs, MachineBasicBlock::iterator InsertPt, @@ -7692,12 +7708,24 @@ MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode), MI.getDebugLoc(), true); MachineInstrBuilder MIB(MF, NewMI); + + // Apply the new instruction's register classes constraints. + for (unsigned i = 0; i < MOs.size(); i++) { + const MCOperandInfo &OpInfo = NewMI->getDesc().OpInfo[i]; + ApplyRegClassConstraints(MF, OpInfo, MOs[i]); + } + addOperands(MIB, MOs); // Loop over the rest of the ri operands, converting them over. unsigned NumOps = MI.getDesc().getNumOperands() - 2; for (unsigned i = 0; i != NumOps; ++i) { MachineOperand &MO = MI.getOperand(i + 2); + + // Apply the new instruction's register classes constraints. + const MCOperandInfo &OpInfo = NewMI->getDesc().OpInfo[i + MOs.size() + 1]; + ApplyRegClassConstraints(MF, OpInfo, MO); + MIB.add(MO); } for (unsigned i = NumOps + 2, e = MI.getNumOperands(); i != e; ++i) { @@ -7721,12 +7749,23 @@ MF.CreateMachineInstr(TII.get(Opcode), MI.getDebugLoc(), true); MachineInstrBuilder MIB(MF, NewMI); + unsigned AddIdx = 0; for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); if (i == OpNo) { assert(MO.isReg() && "Expected to fold into reg operand!"); + + // Apply the new instruction's register classes constraints. + for (unsigned j = 0; j < MOs.size(); j++) { + const MCOperandInfo &OpInfo = NewMI->getDesc().OpInfo[i + j]; + ApplyRegClassConstraints(MF, OpInfo, MOs[j]); + } + addOperands(MIB, MOs, PtrOffset); + AddIdx = MOs.size(); } else { + const MCOperandInfo &OpInfo = NewMI->getDesc().OpInfo[i + AddIdx]; + ApplyRegClassConstraints(MF, OpInfo, MO); MIB.add(MO); } }