mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-26 07:24:25 +00:00
Fix PR5614: parts of a physical register def may be killed the rest.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90180 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -163,8 +163,13 @@ private: // Intermediate data structures
|
|||||||
SmallVector<unsigned, 4> &Defs);
|
SmallVector<unsigned, 4> &Defs);
|
||||||
void UpdatePhysRegDefs(MachineInstr *MI, SmallVector<unsigned, 4> &Defs);
|
void UpdatePhysRegDefs(MachineInstr *MI, SmallVector<unsigned, 4> &Defs);
|
||||||
|
|
||||||
/// FindLastPartialDef - Return the last partial def of the specified register.
|
/// FindLastRefOrPartRef - Return the last reference or partial reference of
|
||||||
/// Also returns the sub-registers that're defined by the instruction.
|
/// the specified register.
|
||||||
|
MachineInstr *FindLastRefOrPartRef(unsigned Reg);
|
||||||
|
|
||||||
|
/// FindLastPartialDef - Return the last partial def of the specified
|
||||||
|
/// register. Also returns the sub-registers that're defined by the
|
||||||
|
/// instruction.
|
||||||
MachineInstr *FindLastPartialDef(unsigned Reg,
|
MachineInstr *FindLastPartialDef(unsigned Reg,
|
||||||
SmallSet<unsigned,4> &PartDefRegs);
|
SmallSet<unsigned,4> &PartDefRegs);
|
||||||
|
|
||||||
|
@ -279,6 +279,43 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
|
|||||||
PhysRegUse[SubReg] = MI;
|
PhysRegUse[SubReg] = MI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// FindLastRefOrPartRef - Return the last reference or partial reference of
|
||||||
|
/// the specified register.
|
||||||
|
MachineInstr *LiveVariables::FindLastRefOrPartRef(unsigned Reg) {
|
||||||
|
MachineInstr *LastDef = PhysRegDef[Reg];
|
||||||
|
MachineInstr *LastUse = PhysRegUse[Reg];
|
||||||
|
if (!LastDef && !LastUse)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MachineInstr *LastRefOrPartRef = LastUse ? LastUse : LastDef;
|
||||||
|
unsigned LastRefOrPartRefDist = DistanceMap[LastRefOrPartRef];
|
||||||
|
MachineInstr *LastPartDef = 0;
|
||||||
|
unsigned LastPartDefDist = 0;
|
||||||
|
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||||
|
unsigned SubReg = *SubRegs; ++SubRegs) {
|
||||||
|
MachineInstr *Def = PhysRegDef[SubReg];
|
||||||
|
if (Def && Def != LastDef) {
|
||||||
|
// There was a def of this sub-register in between. This is a partial
|
||||||
|
// def, keep track of the last one.
|
||||||
|
unsigned Dist = DistanceMap[Def];
|
||||||
|
if (Dist > LastPartDefDist) {
|
||||||
|
LastPartDefDist = Dist;
|
||||||
|
LastPartDef = Def;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (MachineInstr *Use = PhysRegUse[SubReg]) {
|
||||||
|
unsigned Dist = DistanceMap[Use];
|
||||||
|
if (Dist > LastRefOrPartRefDist) {
|
||||||
|
LastRefOrPartRefDist = Dist;
|
||||||
|
LastRefOrPartRef = Use;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LastRefOrPartRef;
|
||||||
|
}
|
||||||
|
|
||||||
bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
|
bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
|
||||||
MachineInstr *LastDef = PhysRegDef[Reg];
|
MachineInstr *LastDef = PhysRegDef[Reg];
|
||||||
MachineInstr *LastUse = PhysRegUse[Reg];
|
MachineInstr *LastUse = PhysRegUse[Reg];
|
||||||
@ -373,7 +410,16 @@ bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
|
|||||||
if (NeedDef)
|
if (NeedDef)
|
||||||
PhysRegDef[Reg]->addOperand(MachineOperand::CreateReg(SubReg,
|
PhysRegDef[Reg]->addOperand(MachineOperand::CreateReg(SubReg,
|
||||||
true/*IsDef*/, true/*IsImp*/));
|
true/*IsDef*/, true/*IsImp*/));
|
||||||
LastRefOrPartRef->addRegisterKilled(SubReg, TRI, true);
|
MachineInstr *LastSubRef = FindLastRefOrPartRef(SubReg);
|
||||||
|
if (LastSubRef)
|
||||||
|
LastSubRef->addRegisterKilled(SubReg, TRI, true);
|
||||||
|
else {
|
||||||
|
LastRefOrPartRef->addRegisterKilled(SubReg, TRI, true);
|
||||||
|
PhysRegUse[SubReg] = LastRefOrPartRef;
|
||||||
|
for (const unsigned *SSRegs = TRI->getSubRegisters(SubReg);
|
||||||
|
unsigned SSReg = *SSRegs; ++SSRegs)
|
||||||
|
PhysRegUse[SSReg] = LastRefOrPartRef;
|
||||||
|
}
|
||||||
for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
|
for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
|
||||||
PartUses.erase(*SS);
|
PartUses.erase(*SS);
|
||||||
}
|
}
|
||||||
|
41
test/CodeGen/ARM/2009-11-30-LiveVariablesBug.ll
Normal file
41
test/CodeGen/ARM/2009-11-30-LiveVariablesBug.ll
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
; RUN: llc -mtriple=armv7-eabi -mcpu=cortex-a8 < %s
|
||||||
|
; PR5614
|
||||||
|
|
||||||
|
%"als" = type { i32 (...)** }
|
||||||
|
%"av" = type { %"als" }
|
||||||
|
%"c" = type { %"lsm", %"Vec3", %"av"*, float, i8, float, %"lsm", i8, %"Vec3", %"Vec3", %"Vec3", float, float, float, %"Vec3", %"Vec3" }
|
||||||
|
%"lsm" = type { %"als", %"Vec3", %"Vec3", %"Vec3", %"Vec3" }
|
||||||
|
%"Vec3" = type { float, float, float }
|
||||||
|
|
||||||
|
define arm_aapcs_vfpcc void @foo(%"c"* %this, %"Vec3"* nocapture %adjustment) {
|
||||||
|
entry:
|
||||||
|
switch i32 undef, label %return [
|
||||||
|
i32 1, label %bb
|
||||||
|
i32 2, label %bb72
|
||||||
|
i32 3, label %bb31
|
||||||
|
i32 4, label %bb79
|
||||||
|
i32 5, label %bb104
|
||||||
|
]
|
||||||
|
|
||||||
|
bb: ; preds = %entry
|
||||||
|
ret void
|
||||||
|
|
||||||
|
bb31: ; preds = %entry
|
||||||
|
%0 = call arm_aapcs_vfpcc %"Vec3" undef(%"lsm"* undef) ; <%"Vec3"> [#uses=1]
|
||||||
|
%mrv_gr69 = extractvalue %"Vec3" %0, 1 ; <float> [#uses=1]
|
||||||
|
%1 = fsub float %mrv_gr69, undef ; <float> [#uses=1]
|
||||||
|
store float %1, float* undef, align 4
|
||||||
|
ret void
|
||||||
|
|
||||||
|
bb72: ; preds = %entry
|
||||||
|
ret void
|
||||||
|
|
||||||
|
bb79: ; preds = %entry
|
||||||
|
ret void
|
||||||
|
|
||||||
|
bb104: ; preds = %entry
|
||||||
|
ret void
|
||||||
|
|
||||||
|
return: ; preds = %entry
|
||||||
|
ret void
|
||||||
|
}
|
Reference in New Issue
Block a user