Index: llvm/lib/CodeGen/SplitKit.h =================================================================== --- llvm/lib/CodeGen/SplitKit.h +++ llvm/lib/CodeGen/SplitKit.h @@ -511,7 +511,8 @@ SlotIndex leaveIntvAtTop(MachineBasicBlock &MBB); /// overlapIntv - Indicate that all instructions in range should use the open - /// interval, but also let the complement interval be live. + /// interval if End does not have tied-def usage of the register and in this + /// case compliment interval is used. Let the complement interval be live. /// /// This doubles the register pressure, but is sometimes required to deal with /// register uses after the last valid split point. Index: llvm/lib/CodeGen/SplitKit.cpp =================================================================== --- llvm/lib/CodeGen/SplitKit.cpp +++ llvm/lib/CodeGen/SplitKit.cpp @@ -791,6 +791,12 @@ return VNI->def; } +static bool hasTiedUseOf(MachineInstr &MI, unsigned Reg) { + return any_of(MI.defs(), [Reg](const MachineOperand &MO) { + return MO.isReg() && MO.isTied() && MO.getReg() == Reg; + }); +} + void SplitEditor::overlapIntv(SlotIndex Start, SlotIndex End) { assert(OpenIdx && "openIntv not called before overlapIntv"); const VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Start); @@ -802,6 +808,16 @@ // The complement interval will be extended as needed by LICalc.extend(). if (ParentVNI) forceRecompute(0, *ParentVNI); + + // If the last use is tied to a def, we can't mark it as live for the + // interval which includes only the use. That would cause the tied pair + // to end up in two different intervals. + if (auto *MI = LIS.getInstructionFromIndex(End)) + if (hasTiedUseOf(*MI, Edit->getReg())) { + LLVM_DEBUG(dbgs() << "skip overlap due to tied def at end\n"); + return; + } + LLVM_DEBUG(dbgs() << " overlapIntv [" << Start << ';' << End << "):"); RegAssign.insert(Start, End, OpenIdx); LLVM_DEBUG(dump()); Index: llvm/test/CodeGen/X86/statepoint-invoke-ra1.ll =================================================================== --- llvm/test/CodeGen/X86/statepoint-invoke-ra1.ll +++ llvm/test/CodeGen/X86/statepoint-invoke-ra1.ll @@ -1,10 +1,8 @@ ; REQUIRES: asserts -; RUN: not --crash llc -o /dev/null %s -max-registers-for-gc-values=15 -use-registers-for-gc-values-in-landing-pad=true -verify-regalloc 2>&1 | FileCheck %s +; RUN: llc -o - %s -max-registers-for-gc-values=15 -use-registers-for-gc-values-in-landing-pad=true -verify-regalloc 2>&1 | FileCheck %s -; The test checks the verification catch the case when RA splits live interval in the -; way the def is located after invoke statepoint while use is in landing pad. - -; CHECK: *** Bad machine code: Two-address instruction operands must be identical *** +; CHECK-NOT: *** Bad machine code +; CHECK: wombat target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2" target triple = "x86_64-unknown-linux-gnu"