OSDN Git Service

[MergeFunctions] Don't blindly RAUW a GlobalValue with a ConstantExpr.
authorwhitequark <whitequark@whitequark.org>
Thu, 19 Oct 2017 04:47:48 +0000 (04:47 +0000)
committerwhitequark <whitequark@whitequark.org>
Thu, 19 Oct 2017 04:47:48 +0000 (04:47 +0000)
MergeFunctions uses (through FunctionComparator) a map of GlobalValues
to identifiers because it needs to compare functions and globals
do not have an inherent total order. Thus, FunctionComparator
(through GlobalNumberState) has a ValueMap<GlobalValue *>.

r315852 added a RAUW on globals that may have been previously
encountered by the FunctionComparator, which would replace
a GlobalValue * key with a ConstantExpr *, which is illegal.

This commit adjusts that code path to remove the function being
replaced from the ValueMap as well.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316145 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Utils/FunctionComparator.h
lib/Transforms/IPO/MergeFunctions.cpp

index e0c79a1..7698a06 100644 (file)
@@ -78,6 +78,10 @@ public:
     return MapIter->second;
   }
 
+  void erase(GlobalValue *Global) {
+    GlobalNumbers.erase(Global);
+  }
+
   void clear() {
     GlobalNumbers.clear();
   }
index bffbb8f..512de8f 100644 (file)
@@ -629,6 +629,9 @@ void MergeFunctions::filterInstsUnrelatedToPDI(
 void MergeFunctions::writeThunk(Function *F, Function *G) {
   if (!G->isInterposable() && !MergeFunctionsPDI) {
     if (G->hasGlobalUnnamedAddr()) {
+      // G might have been a key in our GlobalNumberState, and it's illegal
+      // to replace a key in ValueMap<GlobalValue *> with a non-global.
+      GlobalNumbers.erase(G);
       // If G's address is not significant, replace it entirely.
       Constant *BitcastF = ConstantExpr::getBitCast(F, G->getType());
       G->replaceAllUsesWith(BitcastF);