[llvm] r254171 - [bugpoint] Fix "Alias must point to a definition" problems

Hal Finkel via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 26 11:23:50 PST 2015


Author: hfinkel
Date: Thu Nov 26 13:23:49 2015
New Revision: 254171

URL: http://llvm.org/viewvc/llvm-project?rev=254171&view=rev
Log:
[bugpoint] Fix "Alias must point to a definition" problems

GlobalAliases may reference function definitions, but not function declarations.

bugpoint would sometimes create invalid IR by deleting a function's body (thus
mutating a function definition into a declaration) without first 'fixing' any
GlobalAliases that reference that function definition.

This change iteratively prevents that issue. Before deleting a function's body,
it scans the module for GlobalAliases which reference that function. When
found, it eliminates them using replaceAllUsesWith.

Fixes PR20788.

Patch by Nick Johnson!

Modified:
    llvm/trunk/tools/bugpoint/BugDriver.h
    llvm/trunk/tools/bugpoint/CrashDebugger.cpp
    llvm/trunk/tools/bugpoint/ExtractFunction.cpp

Modified: llvm/trunk/tools/bugpoint/BugDriver.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/BugDriver.h?rev=254171&r1=254170&r2=254171&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/BugDriver.h (original)
+++ llvm/trunk/tools/bugpoint/BugDriver.h Thu Nov 26 13:23:49 2015
@@ -321,6 +321,11 @@ void PrintFunctionList(const std::vector
 ///
 void PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs);
 
+// DeleteGlobalInitializer - "Remove" the global variable by deleting its
+// initializer, making it external.
+//
+void DeleteGlobalInitializer(GlobalVariable *GV);
+
 // DeleteFunctionBody - "Remove" the function by deleting all of it's basic
 // blocks, making it external.
 //

Modified: llvm/trunk/tools/bugpoint/CrashDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/CrashDebugger.cpp?rev=254171&r1=254170&r2=254171&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/CrashDebugger.cpp (original)
+++ llvm/trunk/tools/bugpoint/CrashDebugger.cpp Thu Nov 26 13:23:49 2015
@@ -162,7 +162,7 @@ ReduceCrashingGlobalVariables::TestGloba
   // playing with...
   for (GlobalVariable &I : M->globals())
     if (I.hasInitializer() && !GVSet.count(&I)) {
-      I.setInitializer(nullptr);
+      DeleteGlobalInitializer(&I);
       I.setLinkage(GlobalValue::ExternalLinkage);
     }
 
@@ -664,7 +664,7 @@ static bool DebugACrash(BugDriver &BD,
     for (Module::global_iterator I = M->global_begin(), E = M->global_end();
          I != E; ++I)
       if (I->hasInitializer()) {
-        I->setInitializer(nullptr);
+        DeleteGlobalInitializer(&*I);
         I->setLinkage(GlobalValue::ExternalLinkage);
         DeletedInit = true;
       }

Modified: llvm/trunk/tools/bugpoint/ExtractFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ExtractFunction.cpp?rev=254171&r1=254170&r2=254171&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/ExtractFunction.cpp (original)
+++ llvm/trunk/tools/bugpoint/ExtractFunction.cpp Thu Nov 26 13:23:49 2015
@@ -179,11 +179,43 @@ std::unique_ptr<Module> BugDriver::extra
   return NewM;
 }
 
+static void eliminateAliases(GlobalValue *GV) {
+  // First, check whether a GlobalAlias references this definition.
+  // GlobalAlias MAY NOT reference declarations.
+  for (;;) {
+    // 1. Find aliases
+    SmallVector<GlobalAlias*,1> aliases;
+    Module *M = GV->getParent();
+    for (Module::alias_iterator I=M->alias_begin(), E=M->alias_end(); I!=E; ++I)
+      if (I->getAliasee()->stripPointerCasts() == GV)
+        aliases.push_back(&*I);
+    if (aliases.empty())
+      break;
+    // 2. Resolve aliases
+    for (unsigned i=0, e=aliases.size(); i<e; ++i) {
+      aliases[i]->replaceAllUsesWith(aliases[i]->getAliasee());
+      aliases[i]->eraseFromParent();
+    }
+    // 3. Repeat until no more aliases found; there might
+    // be an alias to an alias...
+  }
+}
+
+//
+// DeleteGlobalInitializer - "Remove" the global variable by deleting its initializer,
+// making it external.
+//
+void llvm::DeleteGlobalInitializer(GlobalVariable *GV) {
+  eliminateAliases(GV);
+  GV->setInitializer(nullptr);
+}
 
 // DeleteFunctionBody - "Remove" the function by deleting all of its basic
 // blocks, making it external.
 //
 void llvm::DeleteFunctionBody(Function *F) {
+  eliminateAliases(F);
+
   // delete the body of the function...
   F->deleteBody();
   assert(F->isDeclaration() && "This didn't make the function external!");
@@ -323,10 +355,10 @@ llvm::SplitFunctionsOutOfModule(Module *
                << "' and from test function '" << TestFn->getName() << "'.\n";
         exit(1);
       }
-      I.setInitializer(nullptr); // Delete the initializer to make it external
+      DeleteGlobalInitializer(&I); // Delete the initializer to make it external
     } else {
       // If we keep it in the safe module, then delete it in the test module
-      GV->setInitializer(nullptr);
+      DeleteGlobalInitializer(GV);
     }
   }
 




More information about the llvm-commits mailing list