diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-01-28 16:56:46 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-01-28 16:56:46 +0000 |
commit | f611ae40fdd3815367dd8244fff037f68110fae0 (patch) | |
tree | 800da7065a895621b41cb4b2d6124542bbb9bd72 /lib | |
parent | 7e82200a05d9f8f7d37f3078a40f31ab1be5bf67 (diff) | |
download | llvm-f611ae40fdd3815367dd8244fff037f68110fae0.tar.gz llvm-f611ae40fdd3815367dd8244fff037f68110fae0.tar.bz2 llvm-f611ae40fdd3815367dd8244fff037f68110fae0.tar.xz |
Fix pr14893.
When simplifycfg moves an instruction, it must drop metadata it doesn't know
is still valid with the preconditions changes. In particular, it must drop
the range and tbaa metadata.
The patch implements this with an utility function to drop all metadata not
in a white list.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200322 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/IR/Metadata.cpp | 45 | ||||
-rw-r--r-- | lib/Transforms/Utils/SimplifyCFG.cpp | 8 |
2 files changed, 53 insertions, 0 deletions
diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp index a32d25c92a..ad943de88c 100644 --- a/lib/IR/Metadata.cpp +++ b/lib/IR/Metadata.cpp @@ -16,6 +16,7 @@ #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/Instruction.h" @@ -583,6 +584,50 @@ MDNode *Instruction::getMetadataImpl(StringRef Kind) const { return getMetadataImpl(getContext().getMDKindID(Kind)); } +void Instruction::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) { + SmallSet<unsigned, 5> KnownSet; + KnownSet.insert(KnownIDs.begin(), KnownIDs.end()); + + // Drop debug if needed + if (KnownSet.erase(LLVMContext::MD_dbg)) + DbgLoc = DebugLoc(); + + if (!hasMetadataHashEntry()) + return; // Nothing to remove! + + DenseMap<const Instruction *, LLVMContextImpl::MDMapTy> &MetadataStore = + getContext().pImpl->MetadataStore; + + if (KnownSet.empty()) { + // Just drop our entry at the store. + MetadataStore.erase(this); + setHasMetadataHashEntry(false); + return; + } + + LLVMContextImpl::MDMapTy &Info = MetadataStore[this]; + unsigned I; + unsigned E; + // Walk the array and drop any metadata we don't know. + for (I = 0, E = Info.size(); I != E;) { + if (KnownSet.count(Info[I].first)) { + ++I; + continue; + } + + Info[I] = Info.back(); + Info.pop_back(); + --E; + } + assert(E == Info.size()); + + if (E == 0) { + // Drop our entry at the store. + MetadataStore.erase(this); + setHasMetadataHashEntry(false); + } +} + /// setMetadata - Set the metadata of of the specified kind to the specified /// node. This updates/replaces metadata if already present, or removes it if /// Node is null. diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 0401b9a7f7..effc08edaa 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -2154,6 +2154,14 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI) { Instruction *NewBonus = 0; if (BonusInst) { NewBonus = BonusInst->clone(); + + // If we moved a load, we cannot any longer claim any knowledge about + // its potential value. The previous information might have been valid + // only given the branch precondition. + // For an analogous reason, we must also drop all the metadata whose + // semantics we don't understand. + NewBonus->dropUnknownMetadata(LLVMContext::MD_dbg); + PredBlock->getInstList().insert(PBI, NewBonus); NewBonus->takeName(BonusInst); BonusInst->setName(BonusInst->getName()+".old"); |