summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2009-02-17 23:05:26 +0000
committerDuncan Sands <baldrick@free.fr>2009-02-17 23:05:26 +0000
commitcdf5ffb7fb3215e9ce5556ce896d4f573ab564e4 (patch)
tree4e40bf73e3a2e79d5e7264a85cdee9eb6311f518
parent0d90e5d08b09c8c72927dae70681ad9d2845475e (diff)
downloadllvm-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.cpp24
-rw-r--r--test/Transforms/GlobalDCE/2009-02-17-AliasUsesAliasee.ll4
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 }