diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2016-11-17 07:29:40 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2016-11-17 07:29:40 +0000 |
commit | 4a8fe09040de2dbb7aa865c590a1bb18bf2e4a30 (patch) | |
tree | 7e9ecd816b48b15bf68b92d10bcb4fe0a09cf712 /llvm/lib/CodeGen | |
parent | f2e0d384e148ff9f5d97708a6d78f70915debd5d (diff) | |
download | bcm5719-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.cpp | 20 |
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)) |