Index: lib/LTO/LTOBackend.cpp =================================================================== --- lib/LTO/LTOBackend.cpp +++ lib/LTO/LTOBackend.cpp @@ -407,12 +407,11 @@ convertToDeclaration(GV); }; - // Process functions and global now. - // FIXME: add support for aliases (needs support in convertToDeclaration). - for (auto &GV : Mod) - MaybeDrop(GV); - for (auto &GV : Mod.globals()) - MaybeDrop(GV); + for (Module::global_value_iterator I = Mod.global_value_begin(), + E = Mod.global_value_end(); + I != E;) + // Increment iterator here since MaybeDrop can delete aliases. + MaybeDrop(*I++); } Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream, Index: lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- lib/Transforms/IPO/FunctionImport.cpp +++ lib/Transforms/IPO/FunctionImport.cpp @@ -624,14 +624,23 @@ V->setLinkage(GlobalValue::ExternalLinkage); V->clearMetadata(); V->setComdat(nullptr); - } else - // For now we don't resolve or drop aliases. Once we do we'll - // need to add support here for creating either a function or - // variable declaration, and return the new GlobalValue* for - // the caller to use. - // Support of dropping aliases is required for correct dead code - // elimination performed in thin LTO backends (see 'dropDeadSymbols'). - llvm_unreachable("Expected function or variable"); + } else { + GlobalValue *NewGV; + if (GV.getValueType()->isFunctionTy()) + NewGV = + Function::Create(cast(GV.getValueType()), + GlobalValue::ExternalLinkage, "", GV.getParent()); + else + NewGV = + new GlobalVariable(*GV.getParent(), GV.getValueType(), + /*isConstant*/ false, GlobalValue::ExternalLinkage, + /*init*/ nullptr, "", + /*insertbefore*/ nullptr, GV.getThreadLocalMode(), + GV.getType()->getAddressSpace()); + NewGV->takeName(&GV); + GV.replaceAllUsesWith(NewGV); + GV.eraseFromParent(); + } } /// Fixup WeakForLinker linkages in \p TheModule based on summary analysis. Index: test/LTO/Resolution/X86/not-prevailing-alias.ll =================================================================== --- /dev/null +++ test/LTO/Resolution/X86/not-prevailing-alias.ll @@ -0,0 +1,34 @@ +; Test to ensure that dead alias are dropped by converting to a declaration +; RUN: opt -module-summary %s -o %t1.bc +; RUN: llvm-lto2 run %t1.bc -r %t1.bc,barAlias,x \ +; RUN: -r %t1.bc,bar,x -r %t1.bc,zed,px \ +; RUN: -o %t2.o -save-temps + +; Check that bar and barAlias were dropped to declarations +; RUN: llvm-dis %t2.o.1.1.promote.bc -o - | FileCheck %s --check-prefix=DROP +; DROP-DAG: declare void @bar() +; DROP-DAG: declare void @barAlias() + +; Check that 'barAlias' was not inlined. +; RUN: llvm-objdump -d %t2.o.1 | FileCheck %s +; CHECK: zed: +; CHECK-NEXT: {{.*}} pushq +; CHECK-NEXT: {{.*}} callq 0 + +; Check that 'bar' produced as undefined. +; RUN: llvm-readelf --symbols %t2.o.1 | FileCheck %s --check-prefix=SYMBOLS +; SYMBOLS: NOTYPE GLOBAL DEFAULT UND barAlias +; SYMBOLS: FUNC GLOBAL DEFAULT 2 zed + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@barAlias = alias void(), void()* @bar +define void @bar() { + ret void +} + +define i32 @zed() { + call void @barAlias() + ret i32 1 +}