summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2014-08-20 18:03:00 +0000
committerSanjay Patel <spatel@rotateright.com>2014-08-20 18:03:00 +0000
commitf3cfeef2e9f13c15af1d02b97c25fde6ef971372 (patch)
treeb402c131c5f31c45657cbe0fa6bc7a32a8df4c1c /llvm/lib/CodeGen
parent03e43f8e686fc3140d912940d426409463160a07 (diff)
downloadbcm5719-llvm-f3cfeef2e9f13c15af1d02b97c25fde6ef971372.tar.gz
bcm5719-llvm-f3cfeef2e9f13c15af1d02b97c25fde6ef971372.zip
critical-anti-dependency breaker: don't use reg def info from kill insts (PR20308)
In PR20308 ( http://llvm.org/bugs/show_bug.cgi?id=20308 ), the critical-anti-dependency breaker caused a miscompile because it broke a WAR hazard using a register that it thinks is available based on info from a kill inst. Until PR18663 is solved, we shouldn't use any def/use info from a kill because they are really just nops. This patch adds guard checks for kills around calls to ScanInstruction() where the DefIndices array is set. For good measure, add an assert in ScanInstruction() so we don't hit this bug again. The test case is a reduced version of the code from the bug report. Differential Revision: http://reviews.llvm.org/D4977 llvm-svn: 216114
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/CriticalAntiDepBreaker.cpp19
1 files changed, 17 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/CriticalAntiDepBreaker.cpp b/llvm/lib/CodeGen/CriticalAntiDepBreaker.cpp
index 2eb9f603433..5c643d43ff1 100644
--- a/llvm/lib/CodeGen/CriticalAntiDepBreaker.cpp
+++ b/llvm/lib/CodeGen/CriticalAntiDepBreaker.cpp
@@ -91,7 +91,14 @@ void CriticalAntiDepBreaker::FinishBlock() {
void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
unsigned InsertPosIndex) {
- if (MI->isDebugValue())
+ // Kill instructions can define registers but are really nops, and there might
+ // be a real definition earlier that needs to be paired with uses dominated by
+ // this kill.
+
+ // FIXME: It may be possible to remove the isKill() restriction once PR18663
+ // has been properly fixed. There can be value in processing kills as seen in
+ // the AggressiveAntiDepBreaker class.
+ if (MI->isDebugValue() || MI->isKill())
return;
assert(Count < InsertPosIndex && "Instruction index out of expected range!");
@@ -234,6 +241,7 @@ void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI,
// Update liveness.
// Proceeding upwards, registers that are defed but not used in this
// instruction are now dead.
+ assert(!MI->isKill() && "Attempting to scan a kill instruction");
if (!TII->isPredicated(MI)) {
// Predicated defs are modeled as read + write, i.e. similar to two
@@ -505,7 +513,14 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
unsigned Count = InsertPosIndex - 1;
for (MachineBasicBlock::iterator I = End, E = Begin; I != E; --Count) {
MachineInstr *MI = --I;
- if (MI->isDebugValue())
+ // Kill instructions can define registers but are really nops, and there
+ // might be a real definition earlier that needs to be paired with uses
+ // dominated by this kill.
+
+ // FIXME: It may be possible to remove the isKill() restriction once PR18663
+ // has been properly fixed. There can be value in processing kills as seen
+ // in the AggressiveAntiDepBreaker class.
+ if (MI->isDebugValue() || MI->isKill())
continue;
// Check if this instruction has a dependence on the critical path that
OpenPOWER on IntegriCloud