From: Evan Cheng Date: Tue, 11 Sep 2007 22:34:47 +0000 (+0000) Subject: Sometimes a MI can define a register as well as defining a super-register at the X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=6d6d352ed9bf69f06d8084b76042d7e9b3980cb5;p=oota-llvm.git Sometimes a MI can define a register as well as defining a super-register at the same time. Do not mark the "smaller" def as dead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41871 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp index e8d07bfcaf1..97e8671ca8f 100644 --- a/lib/CodeGen/LiveVariables.cpp +++ b/lib/CodeGen/LiveVariables.cpp @@ -249,9 +249,6 @@ bool LiveVariables::addRegisterDead(unsigned IncomingReg, MachineInstr *MI, } void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) { - // There is a now a proper use, forget about the last partial use. - PhysRegPartUse[Reg] = NULL; - // Turn previous partial def's into read/mod/write. for (unsigned i = 0, e = PhysRegPartDef[Reg].size(); i != e; ++i) { MachineInstr *Def = PhysRegPartDef[Reg][i]; @@ -266,12 +263,15 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) { // A: EAX = ... // B: = AX // Add implicit def to A. - if (PhysRegInfo[Reg] && !PhysRegUsed[Reg]) { + if (PhysRegInfo[Reg] && PhysRegInfo[Reg] != PhysRegPartUse[Reg] && + !PhysRegUsed[Reg]) { MachineInstr *Def = PhysRegInfo[Reg]; if (!Def->findRegisterDefOperand(Reg)) Def->addRegOperand(Reg, true/*IsDef*/,true/*IsImp*/); } + // There is a now a proper use, forget about the last partial use. + PhysRegPartUse[Reg] = NULL; PhysRegInfo[Reg] = MI; PhysRegUsed[Reg] = true; @@ -373,7 +373,8 @@ void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) { } else if (PhysRegPartUse[SubReg]) // Add implicit use / kill to last use of a sub-register. addRegisterKilled(SubReg, PhysRegPartUse[SubReg], true); - else + else if (LastRef != MI) + // This must be a def of the subreg on the same MI. addRegisterDead(SubReg, LastRef); } } @@ -381,7 +382,7 @@ void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) { if (MI) { for (const unsigned *SuperRegs = RegInfo->getSuperRegisters(Reg); unsigned SuperReg = *SuperRegs; ++SuperRegs) { - if (PhysRegInfo[SuperReg]) { + if (PhysRegInfo[SuperReg] && PhysRegInfo[SuperReg] != MI) { // The larger register is previously defined. Now a smaller part is // being re-defined. Treat it as read/mod/write. // EAX = diff --git a/test/CodeGen/PowerPC/2007-09-11-RegCoalescerAssert.ll b/test/CodeGen/PowerPC/2007-09-11-RegCoalescerAssert.ll new file mode 100644 index 00000000000..bb7aba45a96 --- /dev/null +++ b/test/CodeGen/PowerPC/2007-09-11-RegCoalescerAssert.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | llc -march=ppc64 + + %struct.TCMalloc_SpinLock = type { i32 } + +define void @_ZN17TCMalloc_SpinLock4LockEv(%struct.TCMalloc_SpinLock* %this) { +entry: + %tmp3 = call i32 asm sideeffect "1: lwarx $0, 0, $1\0A\09stwcx. $2, 0, $1\0A\09bne- 1b\0A\09isync", "=&r,=*r,r,1,~{dirflag},~{fpsr},~{flags},~{memory}"( i32** null, i32 1, i32* null ) ; [#uses=0] + unreachable +}