summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CriticalAntiDepBreaker.cpp
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2010-10-02 01:49:29 +0000
committerBob Wilson <bob.wilson@apple.com>2010-10-02 01:49:29 +0000
commitf70007e89e7b252abc9dc175aab92191c09bebf7 (patch)
tree0ae7329763da0ee803b70225edd579bfabc847d1 /lib/CodeGen/CriticalAntiDepBreaker.cpp
parentd0669493b8d42544a94bddcd94d635e0701f6415 (diff)
downloadllvm-f70007e89e7b252abc9dc175aab92191c09bebf7.tar.gz
llvm-f70007e89e7b252abc9dc175aab92191c09bebf7.tar.bz2
llvm-f70007e89e7b252abc9dc175aab92191c09bebf7.tar.xz
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
Diffstat (limited to 'lib/CodeGen/CriticalAntiDepBreaker.cpp')
-rw-r--r--lib/CodeGen/CriticalAntiDepBreaker.cpp24
1 files changed, 14 insertions, 10 deletions
diff --git a/lib/CodeGen/CriticalAntiDepBreaker.cpp b/lib/CodeGen/CriticalAntiDepBreaker.cpp
index 44ff9b3cad..4a62cb7d11 100644
--- a/lib/CodeGen/CriticalAntiDepBreaker.cpp
+++ b/lib/CodeGen/CriticalAntiDepBreaker.cpp
@@ -130,21 +130,25 @@ void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
return;
assert(Count < InsertPosIndex && "Instruction index out of expected range!");
- // Any register which was defined within the previous scheduling region
- // may have been rescheduled and its lifetime may overlap with registers
- // in ways not reflected in our current liveness state. For each such
- // 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.
+ 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
+ // may have been rescheduled and its lifetime may overlap with registers
+ // in ways not reflected in our current liveness state. For each such
+ // register, adjust the liveness state to be conservatively correct.
Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);
// Move the def index to the end of the previous region, to reflect
// that the def could theoretically have been scheduled at the end.
DefIndices[Reg] = InsertPosIndex;
}
+ }
PrescanInstruction(MI);
ScanInstruction(MI, Count);
@@ -580,7 +584,7 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
}
// 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.
Classes[NewReg] = Classes[AntiDepReg];
DefIndices[NewReg] = DefIndices[AntiDepReg];