diff options
author | Duncan Sands <baldrick@free.fr> | 2009-02-17 23:05:26 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2009-02-17 23:05:26 +0000 |
commit | cdf5ffb7fb3215e9ce5556ce896d4f573ab564e4 (patch) | |
tree | 4e40bf73e3a2e79d5e7264a85cdee9eb6311f518 | |
parent | 0d90e5d08b09c8c72927dae70681ad9d2845475e (diff) | |
download | llvm-cdf5ffb7fb3215e9ce5556ce896d4f573ab564e4.tar.gz llvm-cdf5ffb7fb3215e9ce5556ce896d4f573ab564e4.tar.bz2 llvm-cdf5ffb7fb3215e9ce5556ce896d4f573ab564e4.tar.xz |
If an alias is dead and so is its aliasee, then globaldce would
crash because the alias would still be using the aliasee when the
aliasee was deleted.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64844 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/IPO/GlobalDCE.cpp | 24 | ||||
-rw-r--r-- | test/Transforms/GlobalDCE/2009-02-17-AliasUsesAliasee.ll | 4 |
2 files changed, 20 insertions, 8 deletions
diff --git a/lib/Transforms/IPO/GlobalDCE.cpp b/lib/Transforms/IPO/GlobalDCE.cpp index a0f8923242..c28d5e3e57 100644 --- a/lib/Transforms/IPO/GlobalDCE.cpp +++ b/lib/Transforms/IPO/GlobalDCE.cpp @@ -82,7 +82,7 @@ bool GlobalDCE::runOnModule(Module &M) { I != E; ++I) { Changed |= RemoveUnusedGlobalValue(*I); // Externally visible aliases are needed. - if (!I->hasInternalLinkage() && !I->hasLinkOnceLinkage()) + if (!I->hasLocalLinkage() && !I->hasLinkOnceLinkage()) GlobalIsNeeded(I); } @@ -107,6 +107,15 @@ bool GlobalDCE::runOnModule(Module &M) { I->deleteBody(); } + // The third pass drops targets of aliases which are dead... + std::vector<GlobalAlias*> DeadAliases; + for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; + ++I) + if (!AliveGlobals.count(I)) { + DeadAliases.push_back(I); + I->setAliasee(0); + } + if (!DeadFunctions.empty()) { // Now that all interferences have been dropped, delete the actual objects // themselves. @@ -128,14 +137,13 @@ bool GlobalDCE::runOnModule(Module &M) { } // Now delete any dead aliases. - for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;) { - Module::alias_iterator J = I++; - if (!AliveGlobals.count(J)) { - RemoveUnusedGlobalValue(*J); - M.getAliasList().erase(J); - ++NumAliases; - Changed = true; + if (!DeadAliases.empty()) { + for (unsigned i = 0, e = DeadAliases.size(); i != e; ++i) { + RemoveUnusedGlobalValue(*DeadAliases[i]); + M.getAliasList().erase(DeadAliases[i]); } + NumAliases += DeadAliases.size(); + Changed = true; } // Make sure that all memory is released diff --git a/test/Transforms/GlobalDCE/2009-02-17-AliasUsesAliasee.ll b/test/Transforms/GlobalDCE/2009-02-17-AliasUsesAliasee.ll new file mode 100644 index 0000000000..8c15c51a4e --- /dev/null +++ b/test/Transforms/GlobalDCE/2009-02-17-AliasUsesAliasee.ll @@ -0,0 +1,4 @@ +; RUN: llvm-as < %s | opt -globaldce + +@A = alias internal void ()* @F +define internal void @F() { ret void } |