Index: lib/Transforms/Scalar/MemCpyOptimizer.cpp =================================================================== --- lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -532,10 +532,19 @@ // position if nothing alias the store memory after this and the store // destination is not in the range. P = &*I; + + // Make sure this position dominate store's address. + if (auto *Addr = dyn_cast(SI->getPointerOperand())) { + DominatorTree &DT = getAnalysis().getDomTree(); + if (DT.dominates(P, Addr)) { + P = nullptr; + break; + } + } + for (; I != E; ++I) { MemoryLocation StoreLoc = MemoryLocation::get(SI); - if (&*I == SI->getOperand(1) || - AA.getModRefInfo(&*I, StoreLoc) != MRI_NoModRef) { + if (AA.getModRefInfo(&*I, StoreLoc) != MRI_NoModRef) { P = nullptr; break; } Index: test/Transforms/MemCpyOpt/fca2memcpy.ll =================================================================== --- test/Transforms/MemCpyOpt/fca2memcpy.ll +++ test/Transforms/MemCpyOpt/fca2memcpy.ll @@ -73,11 +73,10 @@ ret void } - ; The GEP is present after the aliasing store, preventing to move the memcpy before ; (without further analysis/transformation) define void @copyaliaswithproducerinbetween(%S* %src, %S* %dst) { -; CHECK-LABEL: copyalias +; CHECK-LABEL: copyaliaswithproducerinbetween ; CHECK-NEXT: [[LOAD:%[a-z0-9\.]+]] = load %S, %S* %src ; CHECK-NOT: call %1 = load %S, %S* %src