}
// 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);
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);
--- /dev/null
+# 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
+...