aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2011-06-02 21:24:42 +0000
committerEli Friedman <eli.friedman@gmail.com>2011-06-02 21:24:42 +0000
commit70d893e84b0de21205ad042c6c00148d0e3cd74e (patch)
treef07f97f31afbffebe6158cd2fea7067a6eba3299 /lib/Transforms/Scalar
parentcf4cc84738abc5f63a05b0956e756c66c519ded5 (diff)
downloadexternal_llvm-70d893e84b0de21205ad042c6c00148d0e3cd74e.zip
external_llvm-70d893e84b0de21205ad042c6c00148d0e3cd74e.tar.gz
external_llvm-70d893e84b0de21205ad042c6c00148d0e3cd74e.tar.bz2
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')
-rw-r--r--lib/Transforms/Scalar/MemCpyOptimizer.cpp25
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 360639e..be5aa2e 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(),