diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-09-11 22:34:47 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-09-11 22:34:47 +0000 |
commit | e993ca21319b90ed73d5bcf17ee6c55f061bc296 (patch) | |
tree | 330dadf663f20b5312d14120cd31f3c204f3d452 | |
parent | b790f4ac56eda5ddeee5543424f09341523f5bda (diff) | |
download | external_llvm-e993ca21319b90ed73d5bcf17ee6c55f061bc296.zip external_llvm-e993ca21319b90ed73d5bcf17ee6c55f061bc296.tar.gz external_llvm-e993ca21319b90ed73d5bcf17ee6c55f061bc296.tar.bz2 |
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
-rw-r--r-- | lib/CodeGen/LiveVariables.cpp | 13 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/2007-09-11-RegCoalescerAssert.ll | 9 |
2 files changed, 16 insertions, 6 deletions
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp index e8d07bf..97e8671 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 0000000..bb7aba4 --- /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 ) ; <i32> [#uses=0] + unreachable +} |