diff --git a/lib/CodeGen/RegAllocFast.cpp b/lib/CodeGen/RegAllocFast.cpp index c11ae9cce1a..52502a4b821 100644 --- a/lib/CodeGen/RegAllocFast.cpp +++ b/lib/CodeGen/RegAllocFast.cpp @@ -1058,6 +1058,20 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) { } // Third scan. + // Mark all physreg defs as used before allocating virtreg defs. + for (unsigned I = 0; I != DefOpEnd; ++I) { + const MachineOperand &MO = MI.getOperand(I); + if (!MO.isReg() || !MO.isDef() || !MO.getReg() || MO.isEarlyClobber()) + continue; + unsigned Reg = MO.getReg(); + + if (!Reg || !TargetRegisterInfo::isPhysicalRegister(Reg) || + !MRI->isAllocatable(Reg)) + continue; + definePhysReg(MI, Reg, MO.isDead() ? regFree : regReserved); + } + + // Fourth scan. // Allocate defs and collect dead defs. for (unsigned I = 0; I != DefOpEnd; ++I) { const MachineOperand &MO = MI.getOperand(I); @@ -1065,11 +1079,9 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) { continue; unsigned Reg = MO.getReg(); - if (TargetRegisterInfo::isPhysicalRegister(Reg)) { - if (!MRI->isAllocatable(Reg)) continue; - definePhysReg(MI, Reg, MO.isDead() ? regFree : regReserved); + // We have already dealt with phys regs in the previous scan. + if (TargetRegisterInfo::isPhysicalRegister(Reg)) continue; - } MCPhysReg PhysReg = defineVirtReg(MI, I, Reg, CopySrcReg); if (setPhysReg(MI, MI.getOperand(I), PhysReg)) { VirtDead.push_back(Reg); diff --git a/test/CodeGen/X86/virtreg-physreg-def-regallocfast.mir b/test/CodeGen/X86/virtreg-physreg-def-regallocfast.mir new file mode 100644 index 00000000000..6cdac85f96f --- /dev/null +++ b/test/CodeGen/X86/virtreg-physreg-def-regallocfast.mir @@ -0,0 +1,19 @@ +# RUN: llc -o - -mtriple=x86_64-- -run-pass=regallocfast %s | FileCheck %s +# Fast regalloc used to not collect physical register definitions +# before walking and assigning the virtual definition. +# Therefore it was possible for a virtual definition to end up +# using the same register as a later (in terms of operand list) physical +# register. +# Check this does not happen. +# +# PR41790 +--- +name: instruction_with_1virtreg_1physreg_defs +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-NOT: $rax = KILL implicit-def dead $rax + %0:gr64 = KILL implicit-def dead $rax + KILL killed %0 + RET 0 +...