diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -1130,6 +1130,9 @@ } } + // Set of registers allocated to tied defs. + SmallSet AssignedTiedDefs; + // Allocate virtreg defs. if (HasDef) { if (HasVRegDef) { @@ -1213,6 +1216,12 @@ } else { defineVirtReg(MI, OpIdx, Reg); } + if (MO.isTied()) { + LiveRegMap::iterator LRI = findLiveVirtReg(Reg); + assert(LRI != LiveVirtRegs.end() && "LR must be processed"); + assert(LRI->PhysReg != 0 && "register must be allocated"); + AssignedTiedDefs.insert(LRI->PhysReg); + } } } else { // Assign virtual register defs. @@ -1267,6 +1276,8 @@ const uint32_t *Mask = MO.getRegMask(); for (const LiveReg &LR : LiveVirtRegs) { MCPhysReg PhysReg = LR.PhysReg; + if (AssignedTiedDefs.count(PhysReg)) + continue; if (PhysReg != 0 && MachineOperand::clobbersPhysReg(Mask, PhysReg)) displacePhysReg(MI, PhysReg); } diff --git a/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir b/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir @@ -0,0 +1,21 @@ +# RUN: llc -mtriple=x86_64-- -run-pass=regallocfast -o - %s | FileCheck %s + +# Check that fastregalloc does not displace register assigned to tied def when +# RegMask operand is present. STATEPOINT is an example of such instruction. +# Tied def/use must be assigned to the same register. +--- +name: test_relocate +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $rdi + + ; CHECK: renamable [[REG:\$[a-z0-9]+]] = STATEPOINT 0, 0, 0, target-flags(x86-plt) 0, 2, 0, 2, 0, 2, 0, 2, 1, renamable [[REG]](tied-def 0) + + %1:gr64 = COPY $rdi + ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + %1:gr64 = STATEPOINT 0, 0, 0, target-flags(x86-plt) 0, 2, 0, 2, 0, 2, 0, 2, 1, %1(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp + ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + $rax = COPY %1 + RET 0, killed $rax +...