If an alias is dead and so is its aliasee, then globaldce would
authorDuncan Sands <baldrick@free.fr>
Tue, 17 Feb 2009 23:05:26 +0000 (23:05 +0000)
committerDuncan Sands <baldrick@free.fr>
Tue, 17 Feb 2009 23:05:26 +0000 (23:05 +0000)
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

lib/Transforms/IPO/GlobalDCE.cpp
test/Transforms/GlobalDCE/2009-02-17-AliasUsesAliasee.ll [new file with mode: 0644]

index a0f8923242f50107424c10b518f3c8de7b77cec5..c28d5e3e57a06fe0eac2dcd7f76e035e43022fa1 100644 (file)
@@ -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 (file)
index 0000000..8c15c51
--- /dev/null
@@ -0,0 +1,4 @@
+; RUN: llvm-as < %s | opt -globaldce
+
+@A = alias internal void ()* @F
+define internal void @F() { ret void }