diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-06-02 21:24:42 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-06-02 21:24:42 +0000 |
commit | 70d893e84b0de21205ad042c6c00148d0e3cd74e (patch) | |
tree | f07f97f31afbffebe6158cd2fea7067a6eba3299 /lib/Transforms/Scalar/MemCpyOptimizer.cpp | |
parent | cf4cc84738abc5f63a05b0956e756c66c519ded5 (diff) |
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
Diffstat (limited to 'lib/Transforms/Scalar/MemCpyOptimizer.cpp')
-rw-r--r-- | lib/Transforms/Scalar/MemCpyOptimizer.cpp | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 360639ec95..be5aa2ea58 100644 --- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -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(), |