summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2016-11-17 07:29:40 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2016-11-17 07:29:40 +0000
commit4a8fe09040de2dbb7aa865c590a1bb18bf2e4a30 (patch)
tree7e9ecd816b48b15bf68b92d10bcb4fe0a09cf712 /llvm/lib/CodeGen
parentf2e0d384e148ff9f5d97708a6d78f70915debd5d (diff)
downloadbcm5719-llvm-4a8fe09040de2dbb7aa865c590a1bb18bf2e4a30.tar.gz
bcm5719-llvm-4a8fe09040de2dbb7aa865c590a1bb18bf2e4a30.zip
[ImplicitNullCheck] Fix an edge case where we were hoisting incorrectly
ImplicitNullCheck keeps track of one instruction that the memory operation depends on that it also hoists with the memory operation. When hoisting this dependency, it would sometimes clobber a live-in value to the basic block we were hoisting the two things out of. Fix this by explicitly looking for such dependencies. I also noticed two redundant checks on `MO.isDef()` in IsMIOperandSafe. They're redundant since register MachineOperands are either Defs or Uses -- there is no third kind. I'll change the checks to asserts in a later commit. llvm-svn: 287213
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/ImplicitNullChecks.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/ImplicitNullChecks.cpp b/llvm/lib/CodeGen/ImplicitNullChecks.cpp
index 6c35aaac7d2..31d65e69844 100644
--- a/llvm/lib/CodeGen/ImplicitNullChecks.cpp
+++ b/llvm/lib/CodeGen/ImplicitNullChecks.cpp
@@ -268,7 +268,25 @@ bool HazardDetector::isSafeToHoist(MachineInstr *MI,
return false;
assert((!MO.isDef() || RegDefs.count(MO.getReg())) &&
"All defs must be tracked in RegDefs by now!");
- return !MO.isDef() || RegDefs.find(MO.getReg())->second == MI;
+
+ if (!MO.isDef()) {
+ // FIXME: This is unnecessary, we should be able to
+ // assert(MO.isDef()) here.
+ return true;
+ }
+
+ for (unsigned Reg : RegUses)
+ if (TRI.regsOverlap(Reg, MO.getReg()))
+ return false; // We found a write-after-read
+
+ for (auto &OtherDef : RegDefs) {
+ unsigned OtherReg = OtherDef.first;
+ MachineInstr *OtherMI = OtherDef.second;
+ if (OtherMI != MI && TRI.regsOverlap(OtherReg, MO.getReg()))
+ return false;
+ }
+
+ return true;
};
if (!all_of(MI->operands(), IsMIOperandSafe))
OpenPOWER on IntegriCloud