Index: llvm/include/llvm/CodeGen/MachineRegisterInfo.h =================================================================== --- llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -877,6 +877,8 @@ UsedPhysRegMask.setBitsNotInMask(RegMask); } + void collectUsedPhysRegMask(); + const BitVector &getUsedPhysRegsMask() const { return UsedPhysRegMask; } //===--------------------------------------------------------------------===// Index: llvm/lib/CodeGen/MachineRegisterInfo.cpp =================================================================== --- llvm/lib/CodeGen/MachineRegisterInfo.cpp +++ llvm/lib/CodeGen/MachineRegisterInfo.cpp @@ -517,8 +517,9 @@ // used later. for (MCRegAliasIterator AI(PhysReg, TRI, true); AI.isValid(); ++AI) - if (!def_empty(*AI) || isAllocatable(*AI)) + if (!def_empty(*AI) || isAllocatable(*AI) || UsedPhysRegMask.test(PhysReg)) return false; + return true; } @@ -578,6 +579,14 @@ return false; } +void MachineRegisterInfo::collectUsedPhysRegMask() { + for (auto MBBI = MF->begin(), MBBE = MF->end(); MBBI != MBBE; ++MBBI) + for (MachineInstr &MI : MBBI->instrs()) + for (MachineOperand &MO : MI.operands()) + if (MO.isRegMask()) + addPhysRegsUsedFromRegMask(MO.getRegMask()); +} + bool MachineRegisterInfo::isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest) const { if (!SkipRegMaskTest && UsedPhysRegMask.test(PhysReg)) Index: llvm/lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- llvm/lib/CodeGen/RegisterCoalescer.cpp +++ llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -4113,6 +4113,7 @@ MF = &fn; MRI = &fn.getRegInfo(); + MRI->collectUsedPhysRegMask(); const TargetSubtargetInfo &STI = fn.getSubtarget(); TRI = STI.getRegisterInfo(); TII = STI.getInstrInfo(); Index: llvm/lib/CodeGen/TargetInstrInfo.cpp =================================================================== --- llvm/lib/CodeGen/TargetInstrInfo.cpp +++ llvm/lib/CodeGen/TargetInstrInfo.cpp @@ -969,7 +969,7 @@ // If the physreg has no defs anywhere, it's just an ambient register // and we can freely move its uses. Alternatively, if it's allocatable, // it could get allocated to something with a def during allocation. - if (!MRI.isConstantPhysReg(Reg)) + if (!MRI.isConstantPhysReg(Reg) && !isIgnorableUse(MO)) return false; } else { // A physreg def. We can't remat it. Index: llvm/lib/Target/AMDGPU/SIPreAllocateWWMRegs.cpp =================================================================== --- llvm/lib/Target/AMDGPU/SIPreAllocateWWMRegs.cpp +++ llvm/lib/Target/AMDGPU/SIPreAllocateWWMRegs.cpp @@ -101,7 +101,7 @@ LiveInterval &LI = LIS->getInterval(Reg); for (MCRegister PhysReg : RegClassInfo.getOrder(MRI->getRegClass(Reg))) { - if (!MRI->isPhysRegUsed(PhysReg) && + if (!MRI->isPhysRegUsed(PhysReg, true) && Matrix->checkInterference(LI, PhysReg) == LiveRegMatrix::IK_Free) { Matrix->assign(LI, PhysReg); assert(PhysReg != 0); Index: llvm/lib/Target/Mips/MipsRegisterInfo.h =================================================================== --- llvm/lib/Target/Mips/MipsRegisterInfo.h +++ llvm/lib/Target/Mips/MipsRegisterInfo.h @@ -69,6 +69,8 @@ /// Debug information queries. Register getFrameRegister(const MachineFunction &MF) const override; + bool isConstantPhysReg(MCRegister PhysReg) const override; + /// Return GPR register class. virtual const TargetRegisterClass *intRegClass(unsigned Size) const = 0; Index: llvm/lib/Target/Mips/MipsRegisterInfo.cpp =================================================================== --- llvm/lib/Target/Mips/MipsRegisterInfo.cpp +++ llvm/lib/Target/Mips/MipsRegisterInfo.cpp @@ -318,3 +318,7 @@ // sized objects. return MF.getRegInfo().canReserveReg(BP); } + +bool MipsRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { + return PhysReg == Mips::ZERO_64 || PhysReg == Mips::ZERO; +} Index: llvm/lib/Target/X86/X86InstrInfo.h =================================================================== --- llvm/lib/Target/X86/X86InstrInfo.h +++ llvm/lib/Target/X86/X86InstrInfo.h @@ -573,6 +573,13 @@ Optional describeLoadedValue(const MachineInstr &MI, Register Reg) const override; + /// Given \p MO is a PhysReg use return if it can be ignored for the purpose + /// of instruction rematerialization or sinking. + bool isIgnorableUse(const MachineOperand &MO) const override { + // An RIP relative address is a constant. + return MO.getReg() == X86::RIP; + } + protected: /// Commutes the operands in the given instruction by changing the operands /// order and/or changing the instruction's opcode and/or the immediate value