diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2010-12-24 22:23:59 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2010-12-24 22:23:59 +0000 |
commit | 49c7e3e290e4633971cbeac996d8cffbe2aedc1d (patch) | |
tree | 627430c3909bd74187f29587631731abd561e805 /lib/Transforms/Scalar/MemCpyOptimizer.cpp | |
parent | fea753b397823c340608925eb7f3256a64a30017 (diff) |
Fix a thinko pointed out by Frits van Bommel: looking through global variables in isBytewiseValue is not safe.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122550 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/MemCpyOptimizer.cpp')
-rw-r--r-- | lib/Transforms/Scalar/MemCpyOptimizer.cpp | 41 |
1 files changed, 19 insertions, 22 deletions
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp index c6381205c8..27a2f2fdaa 100644 --- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -40,13 +40,6 @@ STATISTIC(NumCpyToSet, "Number of memcpys converted to memset"); /// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated /// byte store (e.g. i16 0x1234), return null. static Value *isBytewiseValue(Value *V) { - // Look through constant globals. - if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) { - if (GV->mayBeOverridden() || !GV->isConstant() || !GV->hasInitializer()) - return 0; - V = GV->getInitializer(); - } - // All byte-wide stores are splatable, even of arbitrary variables. if (V->getType()->isIntegerTy(8)) return V; @@ -793,21 +786,25 @@ bool MemCpyOpt::processMemCpy(MemCpyInst *M) { } // If copying from a constant, try to turn the memcpy into a memset. - if (Value *ByteVal = isBytewiseValue(M->getSource())) { - Value *Ops[] = { - M->getRawDest(), ByteVal, // Start, value - CopySize, // Size - M->getAlignmentCst(), // Alignment - ConstantInt::getFalse(M->getContext()), // volatile - }; - const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() }; - Module *Mod = M->getParent()->getParent()->getParent(); - Function *MemSetF = Intrinsic::getDeclaration(Mod, Intrinsic::memset, Tys, 2); - CallInst::Create(MemSetF, Ops, Ops+5, "", M); - M->eraseFromParent(); - ++NumCpyToSet; - return true; - } + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(M->getSource())) + if (!GV->mayBeOverridden() && GV->isConstant() && GV->hasInitializer()) + if (Value *ByteVal = isBytewiseValue(GV->getInitializer())) { + Value *Ops[] = { + M->getRawDest(), ByteVal, // Start, value + CopySize, // Size + M->getAlignmentCst(), // Alignment + ConstantInt::getFalse(M->getContext()), // volatile + }; + const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() }; + Module *Mod = M->getParent()->getParent()->getParent(); + Function *MemSetF = Intrinsic::getDeclaration(Mod, Intrinsic::memset, + Tys, 2); + CallInst::Create(MemSetF, Ops, Ops+5, "", M); + MD->removeInstruction(M); + M->eraseFromParent(); + ++NumCpyToSet; + return true; + } // The are two possible optimizations we can do for memcpy: // a) memcpy-memcpy xform which exposes redundance for DSE. |