mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-30 16:17:05 +00:00
Fix a miscompile in 186.crafty for Thumb2 that was exposed by Evan's
scheduling change in svn 115121. The CriticalAntiDepBreaker had bad liveness information. It was calculating the KillIndices for one scheduling region in a basic block, rescheduling that region so the KillIndices were no longer valid, and then using those wrong KillIndices to make decisions for the next scheduling region. I've not been able to reduce a small testcase for this. Radar 8502534. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115400 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -130,21 +130,25 @@ void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
|
|||||||
return;
|
return;
|
||||||
assert(Count < InsertPosIndex && "Instruction index out of expected range!");
|
assert(Count < InsertPosIndex && "Instruction index out of expected range!");
|
||||||
|
|
||||||
|
for (unsigned Reg = 0; Reg != TRI->getNumRegs(); ++Reg) {
|
||||||
|
if (KillIndices[Reg] != ~0u) {
|
||||||
|
// If Reg is currently live, then mark that it can't be renamed as
|
||||||
|
// we don't know the extent of its live-range anymore (now that it
|
||||||
|
// has been scheduled).
|
||||||
|
Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);
|
||||||
|
KillIndices[Reg] = Count;
|
||||||
|
} else if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) {
|
||||||
// Any register which was defined within the previous scheduling region
|
// Any register which was defined within the previous scheduling region
|
||||||
// may have been rescheduled and its lifetime may overlap with registers
|
// may have been rescheduled and its lifetime may overlap with registers
|
||||||
// in ways not reflected in our current liveness state. For each such
|
// in ways not reflected in our current liveness state. For each such
|
||||||
// register, adjust the liveness state to be conservatively correct.
|
// register, adjust the liveness state to be conservatively correct.
|
||||||
for (unsigned Reg = 0; Reg != TRI->getNumRegs(); ++Reg)
|
|
||||||
if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) {
|
|
||||||
assert(KillIndices[Reg] == ~0u && "Clobbered register is live!");
|
|
||||||
|
|
||||||
// Mark this register to be non-renamable.
|
|
||||||
Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);
|
Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);
|
||||||
|
|
||||||
// Move the def index to the end of the previous region, to reflect
|
// Move the def index to the end of the previous region, to reflect
|
||||||
// that the def could theoretically have been scheduled at the end.
|
// that the def could theoretically have been scheduled at the end.
|
||||||
DefIndices[Reg] = InsertPosIndex;
|
DefIndices[Reg] = InsertPosIndex;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PrescanInstruction(MI);
|
PrescanInstruction(MI);
|
||||||
ScanInstruction(MI, Count);
|
ScanInstruction(MI, Count);
|
||||||
@@ -580,7 +584,7 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We just went back in time and modified history; the
|
// We just went back in time and modified history; the
|
||||||
// liveness information for the anti-depenence reg is now
|
// liveness information for the anti-dependence reg is now
|
||||||
// inconsistent. Set the state as if it were dead.
|
// inconsistent. Set the state as if it were dead.
|
||||||
Classes[NewReg] = Classes[AntiDepReg];
|
Classes[NewReg] = Classes[AntiDepReg];
|
||||||
DefIndices[NewReg] = DefIndices[AntiDepReg];
|
DefIndices[NewReg] = DefIndices[AntiDepReg];
|
||||||
|
|||||||
Reference in New Issue
Block a user