diff options
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index df900d65cf2..6d0043ba9e0 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -948,6 +948,21 @@ static bool simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase, const SmallVectorImpl<GCRelocateInst *> &Targets) { bool MadeChange = false; + // We must ensure the relocation of derived pointer is defined after + // relocation of base pointer. If we find a relocation corresponding to base + // defined earlier than relocation of base then we move relocation of base + // right before found relocation. We consider only relocation in the same + // basic block as relocation of base. Relocations from other basic block will + // be skipped by optimization and we do not care about them. + for (auto R = RelocatedBase->getParent()->getFirstInsertionPt(); + &*R != RelocatedBase; ++R) + if (auto RI = dyn_cast<GCRelocateInst>(R)) + if (RI->getStatepoint() == RelocatedBase->getStatepoint()) + if (RI->getBasePtrIndex() == RelocatedBase->getBasePtrIndex()) { + RelocatedBase->moveBefore(RI); + break; + } + for (GCRelocateInst *ToReplace : Targets) { assert(ToReplace->getBasePtrIndex() == RelocatedBase->getBasePtrIndex() && "Not relocating a derived object of the original base object"); |

