Index: lib/Transforms/Scalar/GVNHoist.cpp =================================================================== --- lib/Transforms/Scalar/GVNHoist.cpp +++ lib/Transforms/Scalar/GVNHoist.cpp @@ -739,11 +739,12 @@ // of the second based on the first. if (!Repl || firstInBB(I, Repl)) Repl = I; - + bool MoveAccess = true; if (Repl) { // Repl is already in HoistPt: it remains in place. assert(allOperandsAvailable(Repl, HoistPt) && "instruction depends on operands that are not available"); + MoveAccess = false; } else { // When we do not find Repl in HoistPt, select the first in the list // and move it to HoistPt. @@ -772,16 +773,20 @@ } MemoryAccess *NewMemAcc = nullptr; - if (MemoryAccess *MA = MSSA->getMemoryAccess(Repl)) { - if (MemoryUseOrDef *OldMemAcc = dyn_cast(MA)) { - // The definition of this ld/st will not change: ld/st hoisting is - // legal when the ld/st is not moved past its current definition. - MemoryAccess *Def = OldMemAcc->getDefiningAccess(); - NewMemAcc = MSSA->createMemoryAccessInBB(Repl, Def, HoistPt, - MemorySSA::End); - OldMemAcc->replaceAllUsesWith(NewMemAcc); - MSSA->removeMemoryAccess(OldMemAcc); + if (MoveAccess) { + if (MemoryAccess *MA = MSSA->getMemoryAccess(Repl)) { + if (MemoryUseOrDef *OldMemAcc = dyn_cast(MA)) { + // The definition of this ld/st will not change: ld/st hoisting is + // legal when the ld/st is not moved past its current definition. + MemoryAccess *Def = OldMemAcc->getDefiningAccess(); + NewMemAcc = MSSA->createMemoryAccessInBB(Repl, Def, HoistPt, + MemorySSA::End); + OldMemAcc->replaceAllUsesWith(NewMemAcc); + MSSA->removeMemoryAccess(OldMemAcc); + } } + } else { + NewMemAcc = MSSA->getMemoryAccess(Repl); } if (isa(Repl))