PR10067: Add missing safety check to call return transformation in MemCpyOpt::processStore. If something accesses the dest of the "copy" between the call and the copy, the performCallSlotOptzn transformation is not valid.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132485 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman
2011-06-02 21:24:42 +00:00
parent cf4cc84738
commit 70d893e84b
2 changed files with 57 additions and 4 deletions

View File

@@ -488,11 +488,28 @@ bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
// a memcpy.
if (LoadInst *LI = dyn_cast<LoadInst>(SI->getOperand(0))) {
if (!LI->isVolatile() && LI->hasOneUse()) {
MemDepResult dep = MD->getDependency(LI);
MemDepResult ldep = MD->getDependency(LI);
CallInst *C = 0;
if (dep.isClobber() && !isa<MemCpyInst>(dep.getInst()))
C = dyn_cast<CallInst>(dep.getInst());
if (ldep.isClobber() && !isa<MemCpyInst>(ldep.getInst()))
C = dyn_cast<CallInst>(ldep.getInst());
if (C) {
// Check that nothing touches the dest of the "copy" between
// the call and the store.
MemDepResult sdep = MD->getDependency(SI);
if (!sdep.isNonLocal()) {
bool FoundCall = false;
for (BasicBlock::iterator I = SI, E = sdep.getInst(); I != E; --I) {
if (&*I == C) {
FoundCall = true;
break;
}
}
if (!FoundCall)
C = 0;
}
}
if (C) {
bool changed = performCallSlotOptzn(LI,
SI->getPointerOperand()->stripPointerCasts(),