From d880309835d89413b5cbf4e586d9d0ece4556ece Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Thu, 15 Sep 2016 20:26:27 +0000 Subject: [PATCH] [GlobalOpt] Dead Eliminate declarations GlobalOpt is already dead-code-eliminating global definitions. With this change it also takes care of declarations. Hopefully this should make it now a strict superset of GlobalDCE. This is important for LTO/ThinLTO as we don't want the linker to see "undefined reference" when it processes the input files: it could prevent proper internalization (or even load an extra file from a static archive, changing the behavior of the program!). llvm-svn: 281653 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp | 4 ++-- llvm/test/Transforms/GlobalOpt/deaddeclaration.ll | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Transforms/GlobalOpt/deaddeclaration.ll diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index 52c1cc5..f1686a0 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -1653,7 +1653,7 @@ static bool deleteIfDead(GlobalValue &GV, SmallSet &NotDiscardableComdats) { GV.removeDeadConstantUsers(); - if (!GV.isDiscardableIfUnused()) + if (!GV.isDiscardableIfUnused() && !GV.isDeclaration()) return false; if (const Comdat *C = GV.getComdat()) @@ -1662,7 +1662,7 @@ static bool deleteIfDead(GlobalValue &GV, bool Dead; if (auto *F = dyn_cast(&GV)) - Dead = F->isDefTriviallyDead(); + Dead = (F->isDeclaration() && F->use_empty()) || F->isDefTriviallyDead(); else Dead = GV.use_empty(); if (!Dead) diff --git a/llvm/test/Transforms/GlobalOpt/deaddeclaration.ll b/llvm/test/Transforms/GlobalOpt/deaddeclaration.ll new file mode 100644 index 0000000..942f2e1 --- /dev/null +++ b/llvm/test/Transforms/GlobalOpt/deaddeclaration.ll @@ -0,0 +1,7 @@ +; RUN: opt < %s -globalopt -S | FileCheck %s + +; CHECK-NOT: aa +; CHECK-NOT: bb + +declare void @aa() +@bb = external global i8 -- 2.7.4