summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp15
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");
OpenPOWER on IntegriCloud