aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-09-11 22:34:47 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-09-11 22:34:47 +0000
commite993ca21319b90ed73d5bcf17ee6c55f061bc296 (patch)
tree330dadf663f20b5312d14120cd31f3c204f3d452
parentb790f4ac56eda5ddeee5543424f09341523f5bda (diff)
downloadexternal_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.cpp13
-rw-r--r--test/CodeGen/PowerPC/2007-09-11-RegCoalescerAssert.ll9
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
+}