diff options
author | David L. Jones <dlj@google.com> | 2018-12-13 03:15:11 +0000 |
---|---|---|
committer | David L. Jones <dlj@google.com> | 2018-12-13 03:15:11 +0000 |
commit | 54c01ad6a9e75f01765a45db5fe9775570707079 (patch) | |
tree | 4b79e31e2e626a2bb3624b588fb592ae39ae0f78 /llvm/lib/Transforms | |
parent | 43071080cde59aa1c5b26baa9a187e6a5e180842 (diff) | |
download | bcm5719-llvm-54c01ad6a9e75f01765a45db5fe9775570707079.tar.gz bcm5719-llvm-54c01ad6a9e75f01765a45db5fe9775570707079.zip |
Revert r348645 - "[MemCpyOpt] memset->memcpy forwarding with undef tail"
This revision caused trucated memsets for structs with padding. See:
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20181210/610520.html
llvm-svn: 349002
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp | 46 |
1 files changed, 16 insertions, 30 deletions
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp index fa44cd9e7df..4e82e2bd42c 100644 --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -1144,21 +1144,6 @@ bool MemCpyOptPass::processMemSetMemCpyDependence(MemCpyInst *MemCpy, return true; } -/// Determine whether the instruction has undefined content for the given Size, -/// either because it was freshly alloca'd or started its lifetime. -static bool hasUndefContents(Instruction *I, ConstantInt *Size) { - if (isa<AllocaInst>(I)) - return true; - - if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) - if (II->getIntrinsicID() == Intrinsic::lifetime_start) - if (ConstantInt *LTSize = dyn_cast<ConstantInt>(II->getArgOperand(0))) - if (LTSize->getZExtValue() >= Size->getZExtValue()) - return true; - - return false; -} - /// Transform memcpy to memset when its source was just memset. /// In other words, turn: /// \code @@ -1182,23 +1167,12 @@ bool MemCpyOptPass::performMemCpyToMemSetOptzn(MemCpyInst *MemCpy, if (!AA.isMustAlias(MemSet->getRawDest(), MemCpy->getRawSource())) return false; - // A known memset size is required. + ConstantInt *CopySize = cast<ConstantInt>(MemCpy->getLength()); ConstantInt *MemSetSize = dyn_cast<ConstantInt>(MemSet->getLength()); - if (!MemSetSize) - return false; - // Make sure the memcpy doesn't read any more than what the memset wrote. // Don't worry about sizes larger than i64. - ConstantInt *CopySize = cast<ConstantInt>(MemCpy->getLength()); - if (CopySize->getZExtValue() > MemSetSize->getZExtValue()) { - // If the memcpy is larger than the memset, but the memory was undef prior - // to the memset, we can just ignore the tail. - MemDepResult DepInfo = MD->getDependency(MemSet); - if (DepInfo.isDef() && hasUndefContents(DepInfo.getInst(), CopySize)) - CopySize = MemSetSize; - else - return false; - } + if (!MemSetSize || CopySize->getZExtValue() > MemSetSize->getZExtValue()) + return false; IRBuilder<> Builder(MemCpy); Builder.CreateMemSet(MemCpy->getRawDest(), MemSet->getOperand(1), @@ -1278,7 +1252,19 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M) { if (MemCpyInst *MDep = dyn_cast<MemCpyInst>(SrcDepInfo.getInst())) return processMemCpyMemCpyDependence(M, MDep); } else if (SrcDepInfo.isDef()) { - if (hasUndefContents(SrcDepInfo.getInst(), CopySize)) { + Instruction *I = SrcDepInfo.getInst(); + bool hasUndefContents = false; + + if (isa<AllocaInst>(I)) { + hasUndefContents = true; + } else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { + if (II->getIntrinsicID() == Intrinsic::lifetime_start) + if (ConstantInt *LTSize = dyn_cast<ConstantInt>(II->getArgOperand(0))) + if (LTSize->getZExtValue() >= CopySize->getZExtValue()) + hasUndefContents = true; + } + + if (hasUndefContents) { MD->removeInstruction(M); M->eraseFromParent(); ++NumMemCpyInstr; |