[PATCH] Remove dangling BlockAddresses in GlobalDCE

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Thu Aug 21 05:17:08 PDT 2014


I was stuck with the original bug testcase, this is indeed much smaller and simple :-)
Attached a new patch version, thanks Rafael!

http://reviews.llvm.org/D4932

Files:
  lib/Transforms/IPO/GlobalDCE.cpp
  test/Transforms/GlobalDCE/deadblockaddr.ll

Index: lib/Transforms/IPO/GlobalDCE.cpp
===================================================================
--- lib/Transforms/IPO/GlobalDCE.cpp
+++ lib/Transforms/IPO/GlobalDCE.cpp
@@ -46,6 +46,7 @@
   private:
     SmallPtrSet<GlobalValue*, 32> AliveGlobals;
     SmallPtrSet<Constant *, 8> SeenConstants;
+    SmallPtrSet<Constant *, 8> SeenBlockAddressFnUsers;
 
     /// GlobalIsNeeded - mark the specific global value as needed, and
     /// recursively mark anything that it uses as also needed.
@@ -192,6 +193,11 @@
     Changed = true;
   }
 
+  // Some global initializers elements may leave dead references to functions,
+  // (e.g. BlockAddresses), clean them up.
+  for (auto F : SeenBlockAddressFnUsers)
+    F->removeDeadConstantUsers();
+
   // Make sure that all memory is released
   AliveGlobals.clear();
   SeenConstants.clear();
@@ -231,6 +237,12 @@
             GlobalIsNeeded(GV);
           else if (Constant *C = dyn_cast<Constant>(*U))
             MarkUsedGlobalsAsNeeded(C);
+
+    // Keep track of functions used by BlockAddresses; global initializers
+    // may leave dangling BlockAddresses referring to those.
+    for (auto UB = G->user_begin(), UE = G->user_end(); UB != UE; ++UB)
+      if (isa<BlockAddress>(*UB))
+        SeenBlockAddressFnUsers.insert(G);
   }
 }
 
Index: test/Transforms/GlobalDCE/deadblockaddr.ll
===================================================================
--- /dev/null
+++ test/Transforms/GlobalDCE/deadblockaddr.ll
@@ -0,0 +1,16 @@
+; RUN: opt -globaldce -simplifycfg -S < %s | FileCheck %s
+
+; Tests whether globaldce does the right cleanup while removing @bar
+; so that a dead BlockAddress reference to foo won't prevent other passes
+; to work properly, e.g. simplifycfg
+ at bar = internal unnamed_addr constant i8* blockaddress(@foo, %L1)
+
+; CHECK-LABEL: foo
+; CHECK-NOT: br label %L1
+; CHECK: ret void
+define void @foo() {
+entry:
+  br label %L1
+L1:
+  ret void
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4932.12759.patch
Type: text/x-patch
Size: 1946 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140821/5472745b/attachment.bin>


More information about the llvm-commits mailing list