Fix PR5024. LiveVariables::FindLastPartialDef should return a set of sub-registers that were defined by the last partial def, not just a single sub-register.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82535 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2009-09-22 08:34:46 +00:00
parent a177492108
commit 60c7df2c93
2 changed files with 36 additions and 6 deletions

View File

@ -180,9 +180,9 @@ void LiveVariables::HandleVirtRegDef(unsigned Reg, MachineInstr *MI) {
} }
/// FindLastPartialDef - Return the last partial def of the specified register. /// FindLastPartialDef - Return the last partial def of the specified register.
/// Also returns the sub-register that's defined. /// Also returns the sub-registers that're defined by the instruction.
MachineInstr *LiveVariables::FindLastPartialDef(unsigned Reg, MachineInstr *LiveVariables::FindLastPartialDef(unsigned Reg,
unsigned &PartDefReg) { SmallSet<unsigned,4> &PartDefRegs) {
unsigned LastDefReg = 0; unsigned LastDefReg = 0;
unsigned LastDefDist = 0; unsigned LastDefDist = 0;
MachineInstr *LastDef = NULL; MachineInstr *LastDef = NULL;
@ -198,7 +198,23 @@ MachineInstr *LiveVariables::FindLastPartialDef(unsigned Reg,
LastDefDist = Dist; LastDefDist = Dist;
} }
} }
PartDefReg = LastDefReg;
if (!LastDef)
return 0;
PartDefRegs.insert(LastDefReg);
for (unsigned i = 0, e = LastDef->getNumOperands(); i != e; ++i) {
MachineOperand &MO = LastDef->getOperand(i);
if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0)
continue;
unsigned DefReg = MO.getReg();
if (TRI->isSubRegister(Reg, DefReg)) {
PartDefRegs.insert(DefReg);
for (const unsigned *SubRegs = TRI->getSubRegisters(DefReg);
unsigned SubReg = *SubRegs; ++SubRegs)
PartDefRegs.insert(SubReg);
}
}
return LastDef; return LastDef;
} }
@ -216,8 +232,8 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
// ... // ...
// = EAX // = EAX
// All of the sub-registers must have been defined before the use of Reg! // All of the sub-registers must have been defined before the use of Reg!
unsigned PartDefReg = 0; SmallSet<unsigned, 4> PartDefRegs;
MachineInstr *LastPartialDef = FindLastPartialDef(Reg, PartDefReg); MachineInstr *LastPartialDef = FindLastPartialDef(Reg, PartDefRegs);
// If LastPartialDef is NULL, it must be using a livein register. // If LastPartialDef is NULL, it must be using a livein register.
if (LastPartialDef) { if (LastPartialDef) {
LastPartialDef->addOperand(MachineOperand::CreateReg(Reg, true/*IsDef*/, LastPartialDef->addOperand(MachineOperand::CreateReg(Reg, true/*IsDef*/,
@ -228,7 +244,7 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
unsigned SubReg = *SubRegs; ++SubRegs) { unsigned SubReg = *SubRegs; ++SubRegs) {
if (Processed.count(SubReg)) if (Processed.count(SubReg))
continue; continue;
if (SubReg == PartDefReg || TRI->isSubRegister(PartDefReg, SubReg)) if (PartDefRegs.count(SubReg))
continue; continue;
// This part of Reg was defined before the last partial def. It's killed // This part of Reg was defined before the last partial def. It's killed
// here. // here.

View File

@ -0,0 +1,14 @@
; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mattr=+neon
; PR5024
%bar = type { <4 x float> }
%foo = type { %bar, %bar, %bar, %bar }
declare arm_aapcs_vfpcc <4 x float> @bbb(%bar*) nounwind
define arm_aapcs_vfpcc void @aaa(%foo* noalias sret %agg.result, %foo* %tfrm) nounwind {
entry:
%0 = call arm_aapcs_vfpcc <4 x float> @bbb(%bar* undef) nounwind ; <<4 x float>> [#uses=0]
ret void
}